Recover stale React Router route graphs without process restart - #2564
Recover stale React Router route graphs without process restart#2564rjcortese wants to merge 8 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Builder reviewed your changes and found 1 potential issue 🟡
Review Details
Code Review Summary
PR #2564 adds development-time recovery for stale React Router route graphs. It introduces strict stale-load classification, a serialized Vite restart coordinator with bounded fallback attempts, route/config watcher integration, SSR 503 handling with no-store headers, and focused unit/integration coverage. The overall architecture is sound: recovery is limited to development, ordinary HMR changes remain untouched, restart requests are coalesced, and the SSR fallback avoids turning a transient route-graph rebuild into a cacheable response.
Risk: Standard. The main concern is a configuration-parsing edge case that can silently disable recovery for newly added routes. The coordinator, cleanup behavior, error-chain scoping, and SSR cache semantics otherwise look well covered by the added tests. I also excluded a reported HEAD response-body concern because the same body-discarding behavior existed before this PR and is not a regression.
Key Findings
🟡 MEDIUM — Static flatRoutes configurations containing comments are rejected by the parser, so add-route recovery can be disabled for valid configs.
✅ Good patterns: fail-closed stale-error classification, per-module attempt bounds, serialized restarts, explicit no-store fallback headers, and comprehensive integration coverage.
🧪 Browser testing: Will run after this review (PR touches UI-adjacent route/runtime behavior)
| let remaining = options.slice(1, -1); | ||
| if (rootMatch) remaining = remaining.replace(rootMatch[0], ""); | ||
| if (ignoredMatch) remaining = remaining.replace(ignoredMatch[0], ""); | ||
| if (remaining.replace(/[\s,]/g, "")) return undefined; |
There was a problem hiding this comment.
🟡 Comments in a valid flatRoutes config disable add-route recovery
parseFlatRoutesDiscovery treats any text left after removing the recognized properties as an unsupported option, including comments that are valid in a static flatRoutes({...}) call. This returns undefined, leaves discoveryRoots empty, and means a newly added route under the custom root is not recognized by the watcher or recovered until a manual restart; strip comments or use an AST-based static parse while still failing closed for dynamic values.
|
closing this one. i came up with something much better to try |
Summary
Adds automatic recovery for stale React Router route graphs during
agent-native dev, plus unit and integration tests covering the classifier, recovery coordinator, and end-to-end Vite dev server behavior.Problem
During
agent-native dev, deleting or renaming a route file could leave React Router'svirtual:react-router/server-buildreferencing a now-missing file, causing repeatedERR_LOAD_URLSSR failures until the dev server was manually restarted, interrupting the dev workflow.Solution
Introduce a recovery coordinator that classifies stale route errors from the SSR error chain and serializes Vite restarts triggered either proactively by route file watcher topology changes (add/unlink) or reactively as an SSR fallback when a stale-load error is detected. Ordinary content edits, syntax errors, and application-level failures are left untouched to continue using normal HMR.
Key Changes
react-router-dev-recovery.ts/.spec.tswithclassifyStaleReactRouterRouteError,extractViteLoadUrlPath, andcreateReactRouterRecoveryCoordinator:ERR_LOAD_URL+virtual:react-router/server-buildimporter + a path within the configured route scope that is actually absent on disk.persistentStateKey.markSsrSuccess.react-router-dev-recovery.ts) that watches route discovery roots and config files, triggers debounced/serialized rebuilds onadd/unlink/addDir/unlinkDirtopology events, and leaveschangeevents to normal HMR.react-router-route-recovery.integration.spec.ts, a real Vite + React Router dev-server integration test verifying:@agent-native/core.To clone this PR locally use the Github CLI with command
gh pr checkout 2564You can tag me at @BuilderIO for anything you want me to fix or change