TanStack/query · critical
${this.queryHash} data is undefined
Error message
${this.queryHash} data is undefined What it means
Runtime guard in `Query` (`@tanstack/query-core`) after `this.#retryer.start()` resolves. The query function MUST return a defined value; `undefined` is treated as 'no data' because it would make cache state ambiguous and break `data`/`status` semantics. The console error prints the affected `queryHash`, then the same message is thrown to fail the observer.
Source
Thrown at packages/query-core/src/query.ts:575
this.#dispatch({ type: 'continue' })
},
retry: context.options.retry,
retryDelay: context.options.retryDelay,
networkMode: context.options.networkMode,
canRun: () => true,
})
try {
const data = await this.#retryer.start()
// this is more of a runtime guard
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (data === undefined) {
if (process.env.NODE_ENV !== 'production') {
console.error(
`Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ${this.queryHash}`,
)
}
throw new Error(`${this.queryHash} data is undefined`)
}
this.setData(data)
// Notify cache callback
this.#cache.config.onSuccess?.(data, this as Query<any, any, any, any>)
this.#cache.config.onSettled?.(
data,
this.state.error as any,
this as Query<any, any, any, any>,
)
return data
} catch (error) {
if (error instanceof CancelledError) {
if (error.silent) {
// silent cancellation implies a new fetch is going to be started,
// so we piggyback onto that promise
return this.#retryer.promiseView on GitHub (pinned to 159982c80b)
Solutions
- Inspect the queryFn for the matching `queryHash` and ensure every code path returns a non-undefined value.
- Add `return data;` explicitly and avoid bare `return;`.
- If absence is legitimate, model it as `null` and type `TData` accordingly, or split into a separate query that is conditionally enabled.
- Add a test asserting the queryFn returns a defined value for the representative inputs.
Example fix
// before
queryFn: async () => {
const res = await fetch('/api/user')
const json = await res.json()
// forgot to return
}
// after
queryFn: async () => {
const res = await fetch('/api/user')
return res.json()
} Defensive patterns
Strategy: validation
Validate before calling
// Wrap your queryFn to assert a non-undefined return at runtime.
function withDefinedReturn<T>(fn: () => Promise<T>): () => Promise<NonNullable<T>> {
return async () => {
const data = await fn()
if (data === undefined) throw new Error('queryFn returned undefined')
return data as NonNullable<T>
}
} Try / catch
// In an observer error handler, surface the affected queryHash.
catch (e) {
if (e instanceof Error && /data is undefined/.test(e.message)) {
reportIssue(e.message) // contains the queryHash
}
throw e
} Prevention
- Never write a queryFn with an implicit `undefined` return; always `return`.
- Use `as const` or explicit return types so TypeScript flags undefined branches.
- Add unit tests asserting the queryFn returns a defined value.
- If absence is meaningful, model it with `null` and adjust `TData`.
When it happens
Trigger: A `queryFn` with an early `return;` or `return undefined`; a `queryFn` whose only `return` is inside a conditional branch that isn't taken; a `queryFn` that calls an API and forgets to return the response (`api.get()` without `return`); arrow-function shorthand that implicitly returns the wrong expression.
Common situations: Async functions where a code path falls through without returning; refactoring a queryFn and dropping the `return` keyword; `select` returning `undefined`; conditional fetch that returns nothing on a branch; integration tests with mock queryFns returning `undefined`.
Related errors
AI-assisted analysis of TanStack/query@159982c80b (2026-08-12).
Data as JSON: /api/errors/1d7c3874e01a1706.
Report an issue: GitHub.