refactor(router-core): add error when building route tree if trying to add children routes to an index route
It seems some theoretically invalid route tree configurations used to work before https://github.com/TanStack/router/pull/5867 but don't work anymore.
This PR proposes that we add some runtime checks (when NODE_ENV !== 'production') to warn users of such patterns.
Those env checks persist in the dist build of tanstack/router-core distributed through npm
But get erased at build-time (tested w/ Vite rollup 7.1.12) when the production environment is set (vite build --mode production or simply vite build)
Summary by CodeRabbit
- Bug Fixes
- Added development-time validation that surfaces clear errors for invalid route configurations—prevents index routes from having children and ensures parent/child route relationships are consistent, helping catch routing setup mistakes earlier.
🤖 Nx Cloud AI Fix Eligible
An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.
To disable these notifications, a workspace admin can disable them in workspace settings.
View your CI Pipeline Execution ↗ for commit 60e5fea9c778dfafe9d250388e6d23bb6e66b261
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected --targets=test:eslint,test:unit,tes... |
❌ Failed | 16m 37s | View ↗ |
nx run-many --target=build --exclude=examples/*... |
✅ Succeeded | 1m 24s | View ↗ |
☁️ Nx Cloud last updated this comment at 2025-11-18 23:03:58 UTC
Walkthrough
Runtime validation is added (development-only) to BaseRoute construction and child attachment to ensure index routes (non-root routes whose fullPath ends with /) are not assigned child routes and parent-child relationships are consistent.
Changes
| Cohort / File(s) | Summary |
|---|---|
Route validation guards packages/router-core/src/route.ts |
Adds two runtime invariant checks (guarded by NODE_ENV !== 'production'): one in BaseRoute constructor/init to validate parent-child integrity and one in child-attachment logic to prevent index routes (trailing / for non-root) from having children. No public API signatures changed. |
Sequence Diagram(s)
sequenceDiagram
participant Builder as RouterBuilder
participant Base as BaseRoute (init / ctor)
participant AddChildren as RouteAddChildren (attach children)
participant Dev as Developer
Note over Builder,Base: Route creation (dev-only validations applied)
Builder->>Base: construct/init route with optional parent
alt parent exists and is invalid index-parent or missing child relation
Base-->>Dev: throw invariant error (parent-child integrity)
else
Base->>AddChildren: proceed to attach children (if any)
alt route.fullPath ends with '/' and has children
AddChildren-->>Dev: throw invariant error (index route cannot have children)
else
AddChildren->>Builder: children attached (success)
end
end
Estimated code review effort
🎯 2 (Simple) | ⏱️ ~8 minutes
- Localized, small changes in a single file following a consistent pattern.
- Low logic density: two development-only guard clauses.
Areas to review:
- Correct detection of index routes (trailing
/semantics for root vs non-root). - Clarity and correctness of invariant error messages.
Suggested reviewers
- schiller-manuel
Poem
🐰 Hopping through paths with careful paws,
I check each parent, enforce the laws.
No index may sprout a child anew,
I thump and warn, "This won't do!"
Dev-time safety — hops for you ✨
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title directly and specifically describes the main change: adding error validation when children routes are added to index routes during route tree building. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
refactor-router-core-route-errors-w-index-children
Comment @coderabbitai help to get the list of available commands and usage tips.
More templates
- tanstack-router-react-example-authenticated-routes
- tanstack-router-react-example-authenticated-routes-firebase
- tanstack-router-react-example-basic
- tanstack-router-react-example-basic-default-search-params
- tanstack-router-react-example-basic-devtools-panel
- tanstack-router-react-example-basic-file-based
- tanstack-router-react-example-basic-non-nested-devtools
- tanstack-router-react-example-react-query
- tanstack-router-react-example-basic-react-query-file-based
- tanstack-router-react-example-basic-ssr-file-based
- tanstack-router-react-example-basic-ssr-streaming-file-based
- tanstack-router-react-example-basic-virtual-file-based
- tanstack-router-react-example-basic-virtual-inside-file-based
- tanstack-router-react-example-deferred-data
- tanstack-router-i18n-paraglide
- tanstack-router-react-example-kitchen-sink
- tanstack-router-react-example-kitchen-sink-file-based
- tanstack-router-react-example-kitchen-sink-react-query
- tanstack-router-react-example-kitchen-sink-react-query-file-based
- tanstack-router-react-example-large-file-based
- tanstack-router-react-example-location-masking
- tanstack-router-react-example-navigation-blocking
- tanstack-router-react-example-quickstart
- tanstack-router-react-example-quickstart-esbuild-file-based
- tanstack-router-react-example-quickstart-file-based
- tanstack-router-react-example-quickstart-rspack-file-based
- tanstack-router-react-example-quickstart-webpack-file-based
- router-monorepo-react-query
- router-mono-simple
- router-mono-simple-lazy
- tanstack-router-react-example-scroll-restoration
- tanstack-search-validator-adapters
- tanstack-start-example-bare
- tanstack-start-example-basic
- tanstack-start-example-basic-auth
- tanstack-start-example-basic-cloudflare
- tanstack-start-example-basic-react-query
- tanstack-start-example-basic-static
- tanstack-start-bun-hosting
- tanstack-start-example-clerk-basic
- tanstack-start-example-convex-trellaux
- tanstack-start-example-counter
- tanstack-start-i18n-paraglide
- tanstack-start-example-large
- tanstack-start-example-material-ui
- tanstack-start-streaming-data-from-server-functions
- tanstack-start-example-supabase-basic
- tanstack-start-tailwind-v4
- tanstack-start-example-trellaux
- tanstack-start-example-workos
- tanstack-router-react-example-view-transitions
- tanstack-router-react-example-with-framer-motion
- tanstack-router-react-example-with-trpc
- tanstack-router-react-example-with-trpc-react-query
- tanstack-router-solid-example-authenticated-routes
- tanstack-router-solid-example-authenticated-routes-firebase
- tanstack-router-solid-example-basic
- tanstack-router-solid-example-basic-default-search-params
- tanstack-router-solid-example-basic-devtools-panel
- tanstack-router-solid-example-basic-file-based
- tanstack-router-solid-example-basic-non-nested-devtools
- tanstack-router-solid-example-basic-solid-query
- tanstack-router-solid-example-basic-solid-query-file-based
- tanstack-router-solid-example-basic-ssr-file-based
- tanstack-router-solid-example-basic-ssr-streaming-file-based
- tanstack-router-solid-example-basic-virtual-file-based
- tanstack-router-solid-example-basic-virtual-inside-file-based
- tanstack-router-solid-example-deferred-data
- tanstack-router-solid-i18n-paraglide
- tanstack-router-solid-example-kitchen-sink
- tanstack-router-solid-example-kitchen-sink-file-based
- tanstack-router-solid-example-kitchen-sink-solid-query
- tanstack-router-solid-example-kitchen-sink-solid-query-file-based
- tanstack-router-solid-example-large-file-based
- tanstack-router-solid-example-location-masking
- tanstack-router-solid-example-navigation-blocking
- tanstack-router-solid-example-quickstart
- tanstack-router-solid-example-quickstart-esbuild-file-based
- tanstack-router-solid-example-quickstart-file-based
- tanstack-router-solid-example-quickstart-rspack-file-based
- tanstack-router-solid-example-quickstart-webpack-file-based
- router-solid-mono-simple
- router-solid-mono-simple-lazy
- router-solid-monorepo-solid-query
- tanstack-router-solid-example-scroll-restoration
- tanstack-solid-router-search-validator-adapters
- tanstack-solid-start-example-basic
- tanstack-solid-start-example-basic-auth
- tanstack-solid-start-example-basic-cloudflare
- tanstack-solid-start-example-basic-netlify
- tanstack-solid-start-example-basic-nitro
- tanstack-start-example-basic-solid-query
- tanstack-solid-start-example-basic-static
- tanstack-solid-start-bun-hosting
- tanstack-solid-start-example-convex-better-auth
- tanstack-solid-start-example-counter
- tanstack-solid-start-i18n-paraglide
- tanstack-solid-start-example-large
- tanstack-solid-start-streaming-data-from-server-functions
- tanstack-solid-start-example-supabase-basic
- tanstack-solid-start-tailwind-v4
- tanstack-router-solid-example-view-transitions
- tanstack-router-solid-example-with-framer-motion
- tanstack-router-solid-example-with-trpc
@tanstack/arktype-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5897
@tanstack/directive-functions-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5897
@tanstack/eslint-plugin-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5897
@tanstack/history
npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5897
@tanstack/nitro-v2-vite-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5897
@tanstack/react-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5897
@tanstack/react-router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5897
@tanstack/react-router-ssr-query
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5897
@tanstack/react-start
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5897
@tanstack/react-start-client
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5897
@tanstack/react-start-server
npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5897
@tanstack/router-cli
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5897
@tanstack/router-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5897
@tanstack/router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5897
@tanstack/router-devtools-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5897
@tanstack/router-generator
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5897
@tanstack/router-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5897
@tanstack/router-ssr-query-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5897
@tanstack/router-utils
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5897
@tanstack/router-vite-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5897
@tanstack/server-functions-plugin
npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5897
@tanstack/solid-router
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5897
@tanstack/solid-router-devtools
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5897
@tanstack/solid-router-ssr-query
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@5897
@tanstack/solid-start
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5897
@tanstack/solid-start-client
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5897
@tanstack/solid-start-server
npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5897
@tanstack/start-client-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5897
@tanstack/start-plugin-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5897
@tanstack/start-server-core
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5897
@tanstack/start-static-server-functions
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5897
@tanstack/start-storage-context
npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5897
@tanstack/valibot-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5897
@tanstack/virtual-file-routes
npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5897
@tanstack/zod-adapter
npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5897
commit: 60e5fea