Fix Error: Error: Missing slot "modal" in parallel route. Expected to find a `@modal/page.tsx` or `@modal/default.tsx` file. in Next.js
This error occurs when a Next.js parallel route slot is defined in the layout but the corresponding directory does not contain a page.tsx or default.tsx file. Parallel routes require each slot to have at least a default.tsx fallback. Fix it by adding a default.tsx file that returns null to the slot directory.
Reading the Stack Trace
Here's what each line means:
- at collectAppPaths (/app/node_modules/next/dist/build/webpack/loaders/next-app-loader.js:187:15): The app loader scans the directory structure for parallel route slots and cannot find the required files in the @modal directory.
- at async buildAppStaticPaths (/app/node_modules/next/dist/build/utils.js:1053:14): The build system is generating static paths and fails because the parallel route slot is incomplete.
- at async build (/app/node_modules/next/dist/build/index.js:366:9): The Next.js build process fails because the parallel route configuration is invalid.
Common Causes
1. Missing default.tsx in slot directory
The @modal directory exists but only contains a page.tsx for a specific route, without a default.tsx fallback for other routes.
// Directory structure:
// app/
// layout.tsx (uses { modal } prop)
// @modal/
// photo/
// [id]/
// page.tsx
// // Missing: @modal/default.tsx
2. Slot referenced in layout but directory missing
The layout destructures a slot prop that does not have a corresponding @slot directory.
// app/layout.tsx
export default function Layout({ children, modal }: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<div>{children}{modal}</div>
);
}
// But app/@modal/ directory does not exist
3. Incorrect slot directory naming
The slot directory name does not match the prop name used in the layout, often due to capitalization.
// app/@Modal/page.tsx exists but layout uses { modal } (lowercase)
export default function Layout({ children, modal }) {
return <div>{children}{modal}</div>;
}
The Fix
Create a default.tsx file in the @modal slot directory that returns null. This tells Next.js what to render for the slot when no matching route is active. The default export prevents the missing slot error during builds and navigation.
// app/layout.tsx
export default function Layout({
children,
modal,
}: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
// app/@modal/ directory exists but has no default.tsx
// app/layout.tsx
export default function Layout({
children,
modal,
}: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
// app/@modal/default.tsx
export default function ModalDefault() {
return null;
}
Testing the Fix
import { render } from '@testing-library/react';
import ModalDefault from '@/app/@modal/default';
import Layout from '@/app/layout';
describe('Parallel Route - Modal Slot', () => {
it('default.tsx renders null', () => {
const { container } = render(<ModalDefault />);
expect(container.innerHTML).toBe('');
});
it('layout renders children and modal slot', () => {
const { getByText } = render(
<Layout modal={<div>Modal Content</div>}>
<div>Page Content</div>
</Layout>
);
expect(getByText('Page Content')).toBeInTheDocument();
expect(getByText('Modal Content')).toBeInTheDocument();
});
});
Run your tests:
npm test
Pushing Through CI/CD
git checkout -b fix/parallel-route-default-slot,git add src/app/@modal/default.tsx,git commit -m "fix: add default.tsx to @modal parallel route slot",git push origin fix/parallel-route-default-slot
Your CI config should look something like this:
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- run: npm run build
The Full Manual Process: 18 Steps
Here's every step you just went through to fix this one bug:
- Notice the error alert or see it in your monitoring tool
- Open the error dashboard and read the stack trace
- Identify the file and line number from the stack trace
- Open your IDE and navigate to the file
- Read the surrounding code to understand context
- Reproduce the error locally
- Identify the root cause
- Write the fix
- Run the test suite locally
- Fix any failing tests
- Write new tests covering the edge case
- Run the full test suite again
- Create a new git branch
- Commit and push your changes
- Open a pull request
- Wait for code review
- Merge and deploy to production
- Monitor production to confirm the error is resolved
Total time: 30-60 minutes. For one bug.
Or Let bugstack Fix It in Under 2 minutes
Every step above? bugstack does it automatically.
Step 1: Install the SDK
npm install bugstack-sdk
Step 2: Initialize
import { initBugStack } from 'bugstack-sdk'
initBugStack({ apiKey: process.env.BUGSTACK_API_KEY })
Step 3: There is no step 3.
bugstack handles everything from here:
- Captures the stack trace and request context
- Pulls the relevant source files from your GitHub repo
- Analyzes the error and understands the code context
- Generates a minimal, verified fix
- Runs your existing test suite
- Pushes through your CI/CD pipeline
- Deploys to production (or opens a PR for review)
Time from error to fix deployed: Under 2 minutes.
Human involvement: zero.
Try bugstack Free →No credit card. 5-minute setup. Cancel anytime.
Deploying the Fix (Manual Path)
- Create default.tsx in the @modal slot directory.
- Run the Next.js build locally to confirm the parallel route resolves.
- Open a pull request with the default slot file.
- Wait for CI checks to pass on the PR.
- Merge to main and verify parallel routes work in staging.
Frequently Asked Questions
BugStack verifies all parallel route slots have proper default exports, tests the layout rendering, runs your test suite, and confirms the build before marking it safe.
Every fix is delivered as a pull request with full CI validation. Your team reviews and approves before anything reaches production.
Yes. Every @slot directory must have either a page.tsx at the root level or a default.tsx. Without it, navigating to routes that do not match the slot will cause errors.
Parallel routes render multiple pages simultaneously in named slots, while layouts wrap a single page. Parallel routes are ideal for modals, side panels, or split views that need independent navigation.