T
TanStackโ€ข7mo ago
genetic-orange

Apollo preload error "Expected a QueryRef object"

@Lenz Weber-Tronic I'm getting this error when using useReadQuery from a ref created by the preloadQuery function your integration gives. It does appear that the data is still presenting so I'm not exactly sure what's going on. I get the error on both Client & SSR. I know this is not a lot of info to go on. I'll keep poking around.
49 Replies
absent-sapphire
absent-sapphireโ€ข7mo ago
Are you by chance importing ApolloClient from the wrong package? You need to import ApolloClient from "@apollo/client-integration-tanstack-start"
genetic-orange
genetic-orangeOPโ€ข7mo ago
Yes I've got the right imports I believe this proves that
Error in renderToPipeableStream: Invariant Violation: Expected a QueryRef object, but got something else instead.
at new InvariantError (./node_modules/.store/ts-invariant-npm-0.10.3-4657a5b439/package/lib/invariant.cjs:16:28)
at invariant (./node_modules/.store/ts-invariant-npm-0.10.3-4657a5b439/package/lib/invariant.cjs:28:15)
at invariant (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/utilities/globals/invariantWrappers.js:30:44)
at assertWrappedQueryRef (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/internal/cache/QueryReference.js:35:40)
at useReadQuery_ (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/hooks/useReadQuery.js:22:52)
at file://./node_modules/.store/@apollo-client-react-streaming-virtual-4548dbc13c/package/dist/index.ssr.js:465:16
at file://./node_modules/.store/@apollo-client-react-streaming-virtual-4548dbc13c/package/dist/index.ssr.js:481:20
at useReadQuery (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/hooks/useReadQuery.js:18:37)
at ResultsData (./src/routes/_reps/search/$searchTerm.tsx:150:45)
at react-stack-bottom-frame (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:8723:18)
at renderWithHooks (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:4621:19)
at renderElement (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:5056:23)
Error in renderToPipeableStream: Invariant Violation: Expected a QueryRef object, but got something else instead.
at new InvariantError (./node_modules/.store/ts-invariant-npm-0.10.3-4657a5b439/package/lib/invariant.cjs:16:28)
at invariant (./node_modules/.store/ts-invariant-npm-0.10.3-4657a5b439/package/lib/invariant.cjs:28:15)
at invariant (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/utilities/globals/invariantWrappers.js:30:44)
at assertWrappedQueryRef (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/internal/cache/QueryReference.js:35:40)
at useReadQuery_ (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/hooks/useReadQuery.js:22:52)
at file://./node_modules/.store/@apollo-client-react-streaming-virtual-4548dbc13c/package/dist/index.ssr.js:465:16
at file://./node_modules/.store/@apollo-client-react-streaming-virtual-4548dbc13c/package/dist/index.ssr.js:481:20
at useReadQuery (./node_modules/.store/@apollo-client-virtual-720ea7c4f2/package/react/hooks/useReadQuery.js:18:37)
at ResultsData (./src/routes/_reps/search/$searchTerm.tsx:150:45)
at react-stack-bottom-frame (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:8723:18)
at renderWithHooks (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:4621:19)
at renderElement (./node_modules/.store/react-dom-virtual-133f1602fc/package/cjs/react-dom-server.node.development.js:5056:23)
absent-sapphire
absent-sapphireโ€ข7mo ago
Unfortunately, it doesn't prove either way - if you are using the right Apollo Client, that should inject a bit of code into the hooks that runs a moment before the error you are experiencing here. Hmm. The only other thing I can think of would be that you have more than one instance of the @apollo/client package. I've seen that cause an error like this. Is there any way you could share that repo with me? I fear I have to see that myself
genetic-orange
genetic-orangeOPโ€ข7mo ago
Yeah that was my thought too. Causing a different Symbol() to be used right? I'm fairly adept at those kinds of problems dealing with yarn pnp. It appears I only have one instance of all 3 related libraries. Ah wait a sec
Uncaught Error: Switched to client rendering because the server rendering errored:
Uncaught Error: Switched to client rendering because the server rendering errored:
So it only happens on SSR. I was stepping through client execution in browser, and it unwrapped/handled the transported query ref as expected. Let me try to figure out what's happening on SSR execution It's correct that useWrapTransportedQueryRef should be called during SSR right? I guess so since it's bundled in index.ssr.js
absent-sapphire
absent-sapphireโ€ข7mo ago
Yes, that's correct. Essentially, you get a "transported queryRef" in your loader, and both in SSR and in the Browser, it needs to be revived to act as a real queryRef
genetic-orange
genetic-orangeOPโ€ข7mo ago
Gotcha. I believe that is what I'm seeing as well. I think it is symbol shenanigans
absent-sapphire
absent-sapphireโ€ข7mo ago
Maybe ESM/CJS shenanigans?
genetic-orange
genetic-orangeOPโ€ข7mo ago
yeah maybe Stack traces have cjs/react-dom-server.node.development.js - is vinxi/vite supposed to be using CJS for react here (in SSR)? All of the apollo related frames appear to be the ESM files
absent-sapphire
absent-sapphireโ€ข7mo ago
I can only point at https://github.com/apollographql/apollo-client-nextjs/tree/pr/refactor-tests/integration-test/tanstack-start for a comparison Nothing from react/internal/internal.cjs or ./apollo-client.cjs? That would already be good
genetic-orange
genetic-orangeOPโ€ข7mo ago
Correct, neither of those paths
absent-sapphire
absent-sapphireโ€ข7mo ago
I wish I could tell you more about vinxi here.. :/ Maybe clear all caches? I've had tons of fun with old caches
genetic-orange
genetic-orangeOPโ€ข7mo ago
I changed to
var QUERY_REFERENCE_SYMBOL = Symbol.for('apollo.queryRef');
var QUERY_REFERENCE_SYMBOL = Symbol.for('apollo.queryRef');
And now I get an error here promise is undefined ๐Ÿ˜ต
absent-sapphire
absent-sapphireโ€ข7mo ago
Waaah ๐Ÿ˜ฟ Just double-checking, what's your react-router version?
genetic-orange
genetic-orangeOPโ€ข7mo ago
above 99
absent-sapphire
absent-sapphireโ€ข7mo ago
above 99.3 specifically?
genetic-orange
genetic-orangeOPโ€ข7mo ago
$ yarn-list-all | grep tanstack | xargs yarn info --name-only {}
โ”œโ”€ @apollo/client-integration-tanstack-start@npm:0.12.0-alpha.0
โ”œโ”€ @tanstack/react-router@npm:1.102.5
โ”œโ”€ @tanstack/router-devtools@npm:1.102.5
โ”œโ”€ @tanstack/router-generator@npm:1.102.6
โ”œโ”€ @tanstack/start-config@npm:1.102.6
โ”œโ”€ @tanstack/start-server@npm:1.102.6
โ””โ”€ @tanstack/start@npm:1.102.6
$ yarn-list-all | grep tanstack | xargs yarn info --name-only {}
โ”œโ”€ @apollo/client-integration-tanstack-start@npm:0.12.0-alpha.0
โ”œโ”€ @tanstack/react-router@npm:1.102.5
โ”œโ”€ @tanstack/router-devtools@npm:1.102.5
โ”œโ”€ @tanstack/router-generator@npm:1.102.6
โ”œโ”€ @tanstack/start-config@npm:1.102.6
โ”œโ”€ @tanstack/start-server@npm:1.102.6
โ””โ”€ @tanstack/start@npm:1.102.6
absent-sapphire
absent-sapphireโ€ข7mo ago
Oh wow those are making numbers these days That should probably be fine, unless something broke again ๐Ÿ˜…
genetic-orange
genetic-orangeOPโ€ข7mo ago
tried clearing cache, no dice
absent-sapphire
absent-sapphireโ€ข7mo ago
Hmm, I still get
Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong. See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201
when using those new versions so I'm pinning "@tanstack/start-router-manifest": "1.99.0",, but I don't get the error you are seeing
genetic-orange
genetic-orangeOPโ€ข7mo ago
I'm fighting my debugger trying to get it to pause in the useReadQuery
absent-sapphire
absent-sapphireโ€ข7mo ago
That said, for me it's end of the day now - sorry :/ I'll probably be able to take a look or two over the course of the evening, but no guarantees - I hope you can find it!
genetic-orange
genetic-orangeOPโ€ข7mo ago
Hey I appreciate your attention here. I'll keep plugging away. I know how blind you feel without having any of my code to look at.
absent-sapphire
absent-sapphireโ€ข7mo ago
Oh, one thing out of curiosity - does it work if you do a full build and not a dev build? That could give some pointers
genetic-orange
genetic-orangeOPโ€ข7mo ago
Uhh lemme try Haven't even ran that and fighting other things. This is such a big migration for this repo ๐Ÿ˜” What do you recommend for the fetch option of HttpLink?
absent-sapphire
absent-sapphireโ€ข7mo ago
fetch itself is perfectly fine, node has had fetch support for so long already
genetic-orange
genetic-orangeOPโ€ข7mo ago
Just from global right? Having to undo decisions made in 2019 is hard lol
absent-sapphire
absent-sapphireโ€ข7mo ago
You can just remove the whole fetch: ... line from the options ๐Ÿ™‚
genetic-orange
genetic-orangeOPโ€ข7mo ago
perfect Ugh more broken. I'll have to get back to you on that. What's your thought with the full build?
absent-sapphire
absent-sapphireโ€ข7mo ago
Well, it's a build with a bundler, which would probably deduplicate packages as part of the build step, while vite in dev can be wonky
genetic-orange
genetic-orangeOPโ€ข7mo ago
Ah naturally changing the PROMISE_SYMBOL to a shared symbol allows the promise to be set correctly and resolves the use(promise) error Ok yeah that fixes everything. So why is Symbol() re-creating/duplicating Alright I'm an idiot. It was the same problem as before. I should've considered that earlier.
vite: {
resolve: {
alias: [
// Main import/export is interpreted as CJS for some reason
// /index.js is ESM.
// We want to only use the ESM version, not mix the two.
{
find: /^(@apollo\/client(?=\/|$)[^.]*)$/,
replacement: '$1/index.js',
},
vite: {
resolve: {
alias: [
// Main import/export is interpreted as CJS for some reason
// /index.js is ESM.
// We want to only use the ESM version, not mix the two.
{
find: /^(@apollo\/client(?=\/|$)[^.]*)$/,
replacement: '$1/index.js',
},
Somehow this vite was duplicating instances. Possibly that it treated my src separately from your libs that had the /index.js path.
absent-sapphire
absent-sapphireโ€ข7mo ago
Oh no ๐Ÿ˜ฆ But hey, you found it! ๐ŸŽ‰ (Also, currently working on AC 4.0 where you won't need that hack anymore)
genetic-orange
genetic-orangeOPโ€ข7mo ago
Sweet! I peeked at that roadmap yesterday. Exciting Alright back at it. It looks like resolve.alias is passed directly to rollup. Maybe rollup is not used in dev mode? or maybe it is with libraries? I just got that preamble hmr error too
absent-sapphire
absent-sapphireโ€ข7mo ago
Oh dang. Life is fun
genetic-orange
genetic-orangeOPโ€ข7mo ago
Truly. You have a quick answer on when rollup is used to save me researching?
absent-sapphire
absent-sapphireโ€ข7mo ago
Nope, I'm sorry ๐Ÿ˜ฆ
genetic-orange
genetic-orangeOPโ€ข7mo ago
How come this @apollo/client/index.js is even needed? Is it just the package.json declarations cannot be updated without a perceived breaking change? Bah I give up. I'll just re-export the apollo hooks from a src path that I can alias, and remove the resolve alias nonsense.
import { useReadQuery } from '~/api'
import { useReadQuery } from '~/api'
seems cleaner anyways.
absent-sapphire
absent-sapphireโ€ข7mo ago
Yeah, can't add an exports field without a major release unfortunately :/
absent-sapphire
absent-sapphireโ€ข7mo ago
genetic-orange
genetic-orangeOPโ€ข7mo ago
Huge! Next road block is MUI/Emotion preloadQuery seems nice because I can share the query ref amoungst multiple components. But there's no way to disable actually running that query in SSR right?
absent-sapphire
absent-sapphireโ€ข7mo ago
Loaders run in the first render on SSR, so not really. But why would you? It won't rerun in the browser, data gets transported over
genetic-orange
genetic-orangeOPโ€ข7mo ago
Well because fullfilling the data renders the data components which create emotion styles, but those emotion styles are not streamed because they don't support that ๐Ÿ˜’
absent-sapphire
absent-sapphireโ€ข7mo ago
Or the other way round - why SSR if you don't want your data available to SSR? Fun.
genetic-orange
genetic-orangeOPโ€ข7mo ago
Seems like a solution there would be similar to what you are doing with apollo data
absent-sapphire
absent-sapphireโ€ข7mo ago
But weird enough. Are you on React 19? For styles it's easier than for data, React has primitives for that in 19 so I'd assume they support that by now
genetic-orange
genetic-orangeOPโ€ข7mo ago
But that is black magic, even for me, and I don't have the bandwidth to write that for emotion one would think trying to migrate to 19 as well. I'm big banging everything at once and it's working out super well let me tell you lol What's your suggestion to share some data loading ala query ref but no SSR? Just a custom hook function?
absent-sapphire
absent-sapphireโ€ข7mo ago
At least I thought they had added that api, something like preloadStyle, but I only see https://react.dev/reference/react-dom/preload Hm, can't you disable ssr completely? You don't seem to get mileage out of it atm. Or replace your emotion components with skeletons while on the server
genetic-orange
genetic-orangeOPโ€ข7mo ago
Well I had that thought. But I'm still hoping I can get auth0 auth to load in SSR
absent-sapphire
absent-sapphireโ€ข7mo ago
const isClient = useSyncExternalStore(() => {}, () => true, () => false)
const isClient = useSyncExternalStore(() => {}, () => true, () => false)
Anyways... 1:30 am - ๐Ÿ’ค
genetic-orange
genetic-orangeOPโ€ข7mo ago
Yes dinner time for me. More to work out next week. Appreciate your input!

Did you find this page helpful?