Describe the bug
When a select function throws, the error is stored on the observer (#selectError) and surfaced on every result. It is only ever cleared inside the select block itself — which is skipped entirely while data is undefined (queryObserver.ts, createResult). So after switching the observer to a different queryKey (or after resetQueries), the new pending query reports status: 'error' carrying the previous query's select error. With throwOnError or suspense, the stale error is thrown into the error boundary while the new query is still fetching.
Minimal reproducible example
constobserver=newQueryObserver(queryClient,{queryKey: ['user','a'],queryFn: fetchUser,select: (d)=>d.profile.name,// throws for user "a"})observer.subscribe(()=>{})// select throws -> status 'error' (correct)observer.setOptions({queryKey: ['user','b'],// different, healthy queryqueryFn: fetchUser,select: (d)=>d.profile.name,})observer.getCurrentResult().status// 'error' with user "a"'s error — expected 'pending'Equivalent in React: useQuery({ queryKey: ['user', id], ... }) where select throws for id "a", then setting id to "b".
Second repro without a key change: after the select error, call queryClient.resetQueries({ queryKey }) — the reset pending state still carries the old select error.
Expected behavior
While the new (or reset) query is fetching and has no data, the result should be { status: 'pending', error: null }. A select error belongs to the data it was computed from; once that data is gone, it should not leak into the next result.
Platform
@tanstack/query-core (all adapters affected), reproduced on main
Additional context
The cause is that createResult only clears #selectError on a successful select run inside the options.select && data !== undefined block; the if (this.#selectError) check below it then fires unconditionally. Related but distinct from #11011 (which fixes isPlaceholderData when select throws on placeholder data).
I have a fix with regression tests ready and will open a PR.
Describe the bug
When a
selectfunction throws, the error is stored on the observer (#selectError) and surfaced on every result. It is only ever cleared inside the select block itself — which is skipped entirely whiledataisundefined(queryObserver.ts,createResult). So after switching the observer to a differentqueryKey(or afterresetQueries), the new pending query reportsstatus: 'error'carrying the previous query's select error. WiththrowOnErroror suspense, the stale error is thrown into the error boundary while the new query is still fetching.Minimal reproducible example
Equivalent in React:
useQuery({ queryKey: ['user', id], ... })whereselectthrows for id "a", then setting id to "b".Second repro without a key change: after the select error, call
queryClient.resetQueries({ queryKey })— the reset pending state still carries the old select error.Expected behavior
While the new (or reset) query is fetching and has no data, the result should be
{ status: 'pending', error: null }. A select error belongs to the data it was computed from; once that data is gone, it should not leak into the next result.Platform
@tanstack/query-core(all adapters affected), reproduced onmainAdditional context
The cause is that
createResultonly clears#selectErroron a successful select run inside theoptions.select && data !== undefinedblock; theif (this.#selectError)check below it then fires unconditionally. Related but distinct from #11011 (which fixesisPlaceholderDatawhen select throws on placeholder data).I have a fix with regression tests ready and will open a PR.