Summary
Client-side navigation into a lazy()-loaded route hangs forever — the <Loading> fallback never resolves — when the route reads a query()-backed value that is itself gated behind a separate, already-pending query()-backed value:
const orgId = createMemo(() => profile()?.orgId);
const record = createMemo(() => {
const oid = orgId();
return oid ? getRecord(oid) : undefined;
});
This is a very common pattern — "wait for the session/org to resolve before fetching anything that depends on it." It works correctly on 2.0.0-next.19 and regresses starting at 2.0.0-next.20 (also broken on next.21, latest as of this report).
Reproduction
Minimal repo: <link to your pushed solid-router-repro repo here>
pnpm install
pnpm dev
- Open the app, click through to the lazy
/detail/:id route (client-side nav, not a full page load).
- The "Loading record…" fallback never resolves — confirmed stuck after 12+ seconds, not just slow. DevTools shows only the dev-mode
ASYNC_OUTSIDE_LOADING_BOUNDARY / STRICT_READ_UNTRACKED warnings, no thrown error.
- Change
@solidjs/router to 2.0.0-next.19 in package.json, reinstall, repeat the same click: resolves normally.
What was ruled out
- Not a UI or userland issue — reproduces with
solid-js + @solidjs/router only, no UI library involved.
- Not a solid-js/@solidjs/web version issue —
rc.3 and rc.5 both work fine when the router is held at next.19.
- Not about the number of concurrent queries — reproduces with a single gated query, and also with nine spread across multiple panels.
- Not a
query()-specific artifact of memos in general — a raw createMemo(() => somePromise) instead of query() does not hang, on any router version tested. query() specifically is required.
- Not triggered by independent queries — independent (non-gated)
query() calls, i.e. no dependency between them, do not hang. The gating (one query() value depending on another, still-pending query() value) is required to trigger it.
Suspected cause
dist/routing.js changed substantially between next.19 and next.20: the client-side lazy-route-resolution path was rewritten from
throw new NotReadyError(Promise.all(pending.map(resolveLazySubtree)))
to a per-boundary readLazySubtree() that wraps resolveLazySubtree() in runWithOwner(routerOwner, () => createMemo(...)).
That new per-router-owner memo-based reader looks like the prime suspect — the hang only appears on a lazy()-loaded route, and only when a dependent query() chain is involved.
Your Example Website or App
https://stackblitz.com/edit/github-y2k9kdyh-1eadwkhr
Steps to Reproduce the Bug or Issue
- Visit reproduction link
- Click on link
- Observe the route hangs indefinitely
Expected behavior
Route should resolve and load correctly.
Screenshots or Videos
No response
Platform
- solid-js / @solidjs/web: 2.0.0-rc.5
- @solidjs/router: 2.0.0-next.20 (repros) / 2.0.0-next.19 (works)
- Vite 8.2.2, @solidjs/vite-plugin 3.0.0-next.37
- Reproduced in headless Chromium (Playwright) and confirmed with a 12s+ wait
(not a slow-resolve, genuinely stuck)
Additional context
No response
Summary
Client-side navigation into a
lazy()-loaded route hangs forever — the<Loading>fallback never resolves — when the route reads aquery()-backed value that is itself gated behind a separate, already-pendingquery()-backed value:This is a very common pattern — "wait for the session/org to resolve before fetching anything that depends on it." It works correctly on
2.0.0-next.19and regresses starting at2.0.0-next.20(also broken onnext.21, latest as of this report).Reproduction
Minimal repo:
<link to your pushed solid-router-repro repo here>pnpm installpnpm dev/detail/:idroute (client-side nav, not a full page load).ASYNC_OUTSIDE_LOADING_BOUNDARY/STRICT_READ_UNTRACKEDwarnings, no thrown error.@solidjs/routerto2.0.0-next.19inpackage.json, reinstall, repeat the same click: resolves normally.What was ruled out
solid-js+@solidjs/routeronly, no UI library involved.rc.3andrc.5both work fine when the router is held atnext.19.query()-specific artifact of memos in general — a rawcreateMemo(() => somePromise)instead ofquery()does not hang, on any router version tested.query()specifically is required.query()calls, i.e. no dependency between them, do not hang. The gating (onequery()value depending on another, still-pendingquery()value) is required to trigger it.Suspected cause
dist/routing.jschanged substantially betweennext.19andnext.20: the client-side lazy-route-resolution path was rewritten fromto a per-boundary
readLazySubtree()that wrapsresolveLazySubtree()inrunWithOwner(routerOwner, () => createMemo(...)).That new per-router-owner memo-based reader looks like the prime suspect — the hang only appears on a
lazy()-loaded route, and only when a dependentquery()chain is involved.Your Example Website or App
https://stackblitz.com/edit/github-y2k9kdyh-1eadwkhr
Steps to Reproduce the Bug or Issue
Expected behavior
Route should resolve and load correctly.
Screenshots or Videos
No response
Platform
(not a slow-resolve, genuinely stuck)
Additional context
No response