I'm seeing a production crash during hydration. I'm not sure whether this belongs in solid-relay or Relay's experimental fragment observer, but I wanted to start here because the subscription is created from solid-relay's onHydrated path.
When that path subscribes to observeFragmentExperimental, the first emitted snapshot has the aliased connection fields missing from the fragment data. Those fields are non-null in the schema, and the generated Relay type also treats them as present after a complete read, so the component crashes reading actor.followersCount.totalCount.
The fragment:
fragment ProfileCard_actor on Actor {
followeesCount: followees { totalCount }
followersCount: followers { totalCount }
# ...
}
Generated type declares followersCount as { readonly totalCount: number }, not nullable. The schema has followers: ActorFollowersConnection!.
Stacktrace (condensed)
TypeError: Cannot read properties of undefined (reading 'totalCount')
solid.js:294 onHydrated fires
solid-relay:291 subscribes to observeFragmentExperimental
RelayObservable.js:135 subscribe
observeFragmentExperimental.js:64 sink.next(snapshotToFragmentState(...))
ProfileCard.tsx:254 plural(actor.followersCount.totalCount, { ... })
The sequence is: onHydrated fires → solid-relay subscribes to observeFragmentExperimental → the observable immediately emits an initial snapshot → that snapshot is missing the followers/followees linked fields → crash.
I'm not sure which layer is responsible. A few possibilities I can think of: solid-relay may be subscribing before the store has finished reconciling SSR data; observeFragmentExperimental may be emitting a partial snapshot that violates the non-null contract; or the SSR payload may be writing the connection under a different storage key than the one read by the fragment (since followers is used here without args, while other queries might fetch it with pagination args). Happy to dig further if any of these sounds familiar.
Workaround
Optional chaining avoids the crash (actor.followersCount?.totalCount ?? 0), but it works around the generated type rather than explaining why the initial snapshot is missing the field.
Environment
- solid-relay: 1.0.0-beta.20
- relay-runtime: 19.0.0
- solid-js: 1.9.12
I'm seeing a production crash during hydration. I'm not sure whether this belongs in solid-relay or Relay's experimental fragment observer, but I wanted to start here because the subscription is created from solid-relay's
onHydratedpath.When that path subscribes to
observeFragmentExperimental, the first emitted snapshot has the aliased connection fields missing from the fragment data. Those fields are non-null in the schema, and the generated Relay type also treats them as present after a complete read, so the component crashes readingactor.followersCount.totalCount.The fragment:
Generated type declares
followersCountas{ readonly totalCount: number }, not nullable. The schema hasfollowers: ActorFollowersConnection!.Stacktrace (condensed)
The sequence is:
onHydratedfires → solid-relay subscribes toobserveFragmentExperimental→ the observable immediately emits an initial snapshot → that snapshot is missing thefollowers/followeeslinked fields → crash.I'm not sure which layer is responsible. A few possibilities I can think of: solid-relay may be subscribing before the store has finished reconciling SSR data;
observeFragmentExperimentalmay be emitting a partial snapshot that violates the non-null contract; or the SSR payload may be writing the connection under a different storage key than the one read by the fragment (sincefollowersis used here without args, while other queries might fetch it with pagination args). Happy to dig further if any of these sounds familiar.Workaround
Optional chaining avoids the crash (
actor.followersCount?.totalCount ?? 0), but it works around the generated type rather than explaining why the initial snapshot is missing the field.Environment