Skip to content

Commit 5b17c13

Browse files
yanghuidongclaude
andcommitted
fix: capture match reference before redirect navigation removes it
Root cause: When loader throws redirect, the catch block calls inner.router.navigate() which removes the old match from the router. Then finally block tries getMatch(matchId) but returns undefined, so promises never resolve, blocking Promise.allSettled. Solution: Capture match reference BEFORE entering try block, so we have a stable reference even if redirect removes it from router. Flow with redirect: 1. Get matchForCleanup (captures reference) 2. runLoader throws redirect 3. Catch: navigate() removes match from router 4. Finally: Use matchForCleanup (still valid) to resolve promises This allows Promise.allSettled to complete and navigation to proceed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent 2e8a34b commit 5b17c13

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

packages/router-core/src/load-matches.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,8 @@ const loadRouteMatch = async (
836836
} else if (loaderShouldRunAsync && !inner.sync) {
837837
loaderIsRunningAsync = true
838838
;(async () => {
839+
// Capture match reference before try block, because redirect navigation removes it
840+
const matchForCleanup = inner.router.getMatch(matchId)!
839841
try {
840842
await runLoader(inner, matchId, index, route)
841843
commitContext()
@@ -845,13 +847,10 @@ const loadRouteMatch = async (
845847
}
846848
} finally {
847849
// Always resolve promises to allow Promise.allSettled to complete
848-
// Match might be undefined if navigation changed while async loader was running
849-
const match = inner.router.getMatch(matchId)
850-
if (match) {
851-
match._nonReactive.loaderPromise?.resolve()
852-
match._nonReactive.loadPromise?.resolve()
853-
match._nonReactive.loaderPromise = undefined
854-
}
850+
// Use captured reference since navigation might have removed the match
851+
matchForCleanup._nonReactive.loaderPromise?.resolve()
852+
matchForCleanup._nonReactive.loadPromise?.resolve()
853+
matchForCleanup._nonReactive.loaderPromise = undefined
855854
}
856855
})()
857856
} else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {

0 commit comments

Comments
 (0)