nextjs - ✅(Solved) Fix Turbopack `validateAppPaths` misses dynamic slug conflicts when sibling routes have different leaf segments [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#91628Fetched 2026-04-08 01:01:28
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×2commented ×1cross-referenced ×1issue_type_added ×1

Error Message

Error: You cannot use different slug names for the same dynamic path ('item_id' !== 'parent_item_id').

Root Cause

validateAppPaths (build-time) normalizes each route by replacing dynamic segment names with a wildcard and checks for duplicate normalized full paths:

/api/items/[item_id]/details        → /api/items/[*]/details
/api/items/[parent_item_id]/purge   → /api/items/[*]/purge

Because the leaf segments (details vs purge) are different, the normalized paths are different — no conflict detected. Build exits 0.

At runtime, getSortedRoutes builds a trie and enforces that every dynamic segment at the same tree depth shares the same name, regardless of what follows. It catches the item_id vs parent_item_id mismatch immediately and throws.

The gap is directly verifiable:

const { validateAppPaths } = require('next/dist/build/validate-app-paths');
const { getSortedRoutes } = require('next/dist/shared/lib/router/utils/sorted-routes');

const routes = [
  '/api/items/[item_id]/details',
  '/api/items/[parent_item_id]/purge',
];

validateAppPaths(routes);  // no error — build passes ✓
getSortedRoutes(routes);   // throws — runtime crashes ✗

Fix Action

Fixed

PR fix notes

PR #91629: fix : build-time validation for dynamic slug name conflicts in app routes

Description (problem / solution / changelog)

What?

  • Fail next build when app routes have mismatched dynamic slug names at the same path depth.

Why?

  • These conflicts currently slip past validateAppPaths, then crash next start at runtime.

How?

  • Run getSortedRoutes(appPaths) inside validateAppPaths and add a unit test for the sibling-slug mismatch case.

Closes NEXT-

Fixes : #91628

Changed files

  • packages/next/src/build/validate-app-paths.test.ts (modified, +11/-0)
  • packages/next/src/build/validate-app-paths.ts (modified, +3/-0)

Code Example

Compiled successfully
├ ƒ /api/items/[item_id]/details
└ ƒ /api/items/[parent_item_id]/purge   ← no error

---

Error: You cannot use different slug names for the same dynamic path
  ('item_id' !== 'parent_item_id').

---

/api/items/[item_id]/details        → /api/items/[*]/details
/api/items/[parent_item_id]/purge   → /api/items/[*]/purge

---

const { validateAppPaths } = require('next/dist/build/validate-app-paths');
const { getSortedRoutes } = require('next/dist/shared/lib/router/utils/sorted-routes');

const routes = [
  '/api/items/[item_id]/details',
  '/api/items/[parent_item_id]/purge',
];

validateAppPaths(routes);  // no error — build passes ✓
getSortedRoutes(routes);   // throws — runtime crashes ✗

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:15 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.21.1
  npm: 10.9.4
  Yarn: 4.12.0
  pnpm: N/A
Relevant Packages:
  next: 16.1.6
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/pweisensee/nextjs-slug-conflict

To Reproduce

  1. Clone the repo and install: npm install
  2. Run npm run build — exits 0 with no errors, listing both conflicting routes
  3. Run npm start — server crashes immediately before serving any request

Current vs. Expected behavior

Current: next build (with or without --turbo) completes successfully and prints both conflicting routes without any warning or error:

✓ Compiled successfully
├ ƒ /api/items/[item_id]/details
└ ƒ /api/items/[parent_item_id]/purge   ← no error

npm start then crashes immediately:

Error: You cannot use different slug names for the same dynamic path
  ('item_id' !== 'parent_item_id').

Expected: next build should fail with the same error that next start throws, matching the validation already enforced at runtime by getSortedRoutes.


Root cause

validateAppPaths (build-time) normalizes each route by replacing dynamic segment names with a wildcard and checks for duplicate normalized full paths:

/api/items/[item_id]/details        → /api/items/[*]/details
/api/items/[parent_item_id]/purge   → /api/items/[*]/purge

Because the leaf segments (details vs purge) are different, the normalized paths are different — no conflict detected. Build exits 0.

At runtime, getSortedRoutes builds a trie and enforces that every dynamic segment at the same tree depth shares the same name, regardless of what follows. It catches the item_id vs parent_item_id mismatch immediately and throws.

The gap is directly verifiable:

const { validateAppPaths } = require('next/dist/build/validate-app-paths');
const { getSortedRoutes } = require('next/dist/shared/lib/router/utils/sorted-routes');

const routes = [
  '/api/items/[item_id]/details',
  '/api/items/[parent_item_id]/purge',
];

validateAppPaths(routes);  // no error — build passes ✓
getSortedRoutes(routes);   // throws — runtime crashes ✗

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:15 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.21.1
  npm: 10.9.4
  Yarn: 4.12.0
  pnpm: N/A
Relevant Packages:
  next: 16.1.6
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Turbopack, Dynamic Routes

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local), Vercel (Deployed)

Additional context

The error is not caught by TypeScript, ESLint, or next build. It is only visible in server startup logs — by which point the deployment is already live and serving no requests.

On Vercel (Fluid compute), every instance crashes before it can serve a single request. The platform spins up replacements that also crash immediately, creating a crash loop. In our case this drove compute memory costs from ~$0.27/day to $13+/day (~48× increase) in under 15 minutes before we identified and fixed the conflict.

Deployed on: Vercel (Fluid compute). Also reproducible locally with next start.

Suggested fix: validateAppPaths should additionally validate that for any group of routes sharing a common path prefix up to a dynamic segment, the dynamic segment name is consistent across all routes in that group. The simplest implementation would be to call getSortedRoutes on the collected app paths as a final validation step, since getSortedRoutes is already the authoritative validator for this constraint.

extent analysis

Fix Plan

To resolve the issue, we need to modify the validateAppPaths function to validate dynamic segment names consistently. We can achieve this by calling getSortedRoutes as a final validation step.

Step-by-Step Solution

  1. Modify validateAppPaths: Require getSortedRoutes from next/dist/shared/lib/router/utils/sorted-routes.
  2. Call getSortedRoutes: After normalizing paths, call getSortedRoutes with the collected app paths to validate dynamic segment names.
  3. Handle Errors: Catch and handle errors thrown by getSortedRoutes to ensure build-time validation.

Example Code

const { validateAppPaths } = require('next/dist/build/validate-app-paths');
const { getSortedRoutes } = require('next/dist/shared/lib/router/utils/sorted-routes');

const routes = [
  '/api/items/[item_id]/details',
  '/api/items/[parent_item_id]/purge',
];

// Modified validateAppPaths function
function validateAppPathsModified(routes) {
  // Original validation logic...
  validateAppPaths(routes);
  
  try {
    // Call getSortedRoutes for additional validation
    getSortedRoutes(routes);
  } catch (error) {
    // Handle errors thrown by getSortedRoutes
    console.error('Error validating app paths:', error);
    process.exit(1);
  }
}

// Call the modified function
validateAppPathsModified(routes);

Verification

To verify the fix, run next build with the modified validateAppPaths function. The build should now fail with an error when encountering conflicting dynamic segment names.

Extra Tips

  • Ensure that the modified validateAppPaths function is used consistently across the application.
  • Consider adding additional tests to cover the modified validation logic.
  • Review the Next.js documentation for any updates or changes to the validateAppPaths and getSortedRoutes functions.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING