Reproducer: https://github.com/TylerRick/tanstack-solid-ssr-query-adapter-repro (pnpm install && pnpm dev, then open the page — one uncaught error per load)
TypeError: Cannot read properties of undefined (reading 'get')
With a custom serialization adapter registered in start.ts and a route whose loader primes a query through @tanstack/solid-router-ssr-query, the dehydrated query state reaches Solid's own SSR resource stream, not just the router's pipeline. The adapter expression is emitted twice in the HTML:
- inside Solid's stream script (
_$HY.r["0"] = …), bare — $_TSR.t.get("Money")(1234) with no $_TSR.p(...) wrapper, and before the router's $tsr-stream-barrier script defines self.$_TSR. Solid's stream scripts run at parse time, so this throws (or reports $_TSR is not defined when it parses before the router's bootstrap).
- inside the router's barrier script, correctly wrapped in
$_TSR.p(...) and buffered until hydrate() installs the adapter map.
A loader that simply returns the adapter-typed value does not reproduce it — that path is serialized by the router's pipeline alone. It takes the ssr-query dehydration path, which is the ordinary shape for an app reading session/loader data through the query cache. Ours carries a Temporal.PlainDate on the session, so every page load for a user with that field set threw.
Workaround we ship: an inline head script, rendered first, that installs $_TSR as an accessor with a passthrough t map, so nothing throws whichever script parses first and hydrate()'s real map still wins.
Related: #5737 (closed, different cause), #7706 (adapter deserialization broken by calling a server fn from the client entry).
Versions: @tanstack/solid-start / @tanstack/solid-router / @tanstack/solid-router-ssr-query 2.0.0-rc.0, @tanstack/solid-query 6.0.0-rc.0, @tanstack/router-core 1.171.16, solid-js / @solidjs/web 2.0.0-rc.0, vite 8.2.1.
Reproducer: https://github.com/TylerRick/tanstack-solid-ssr-query-adapter-repro (
pnpm install && pnpm dev, then open the page — one uncaught error per load)With a custom serialization adapter registered in
start.tsand a route whose loader primes a query through@tanstack/solid-router-ssr-query, the dehydrated query state reaches Solid's own SSR resource stream, not just the router's pipeline. The adapter expression is emitted twice in the HTML:_$HY.r["0"] = …), bare —$_TSR.t.get("Money")(1234)with no$_TSR.p(...)wrapper, and before the router's$tsr-stream-barrierscript definesself.$_TSR. Solid's stream scripts run at parse time, so this throws (or reports$_TSR is not definedwhen it parses before the router's bootstrap).$_TSR.p(...)and buffered untilhydrate()installs the adapter map.A loader that simply returns the adapter-typed value does not reproduce it — that path is serialized by the router's pipeline alone. It takes the ssr-query dehydration path, which is the ordinary shape for an app reading session/loader data through the query cache. Ours carries a
Temporal.PlainDateon the session, so every page load for a user with that field set threw.Workaround we ship: an inline head script, rendered first, that installs
$_TSRas an accessor with a passthroughtmap, so nothing throws whichever script parses first andhydrate()'s real map still wins.Related: #5737 (closed, different cause), #7706 (adapter deserialization broken by calling a server fn from the client entry).
Versions:
@tanstack/solid-start/@tanstack/solid-router/@tanstack/solid-router-ssr-query2.0.0-rc.0,@tanstack/solid-query6.0.0-rc.0,@tanstack/router-core1.171.16, solid-js /@solidjs/web2.0.0-rc.0, vite 8.2.1.