TanStack/query · error
Expected enabled to be a boolean or a callback that returns
Error message
Expected enabled to be a boolean or a callback that returns a boolean
What it means
Validation in `QueryObserver.setOptions` (`@tanstack/query-core`). `enabled` must be `undefined`, a `boolean`, a `() => boolean` function, or an object that `resolveQueryBoolean` can collapse to a boolean. Anything else (string, number, Promise, array, opaque object) is rejected to prevent silent misbehavior of the observer's fetch gating.
Source
Thrown at packages/query-core/src/queryObserver.ts:159
TError,
TData,
TQueryData,
TQueryKey
>,
): void {
const prevOptions = this.options
const prevQuery = this.#currentQuery
this.options = this.#client.defaultQueryOptions(options)
if (
this.options.enabled !== undefined &&
typeof this.options.enabled !== 'boolean' &&
typeof this.options.enabled !== 'function' &&
typeof resolveQueryBoolean(this.options.enabled, this.#currentQuery) !==
'boolean'
) {
throw new Error(
'Expected enabled to be a boolean or a callback that returns a boolean',
)
}
this.#updateQuery()
this.#currentQuery.setOptions(this.options)
if (
prevOptions._defaulted &&
!shallowEqualObjects(this.options, prevOptions)
) {
this.#client.getQueryCache().notify({
type: 'observerOptionsUpdated',
query: this.#currentQuery,
observer: this,
})
}
View on GitHub (pinned to 159982c80b)
Solutions
- Coerce to boolean: `enabled: Boolean(myValue)` or `enabled: !!myValue`.
- Wrap dynamic resolution in a function: `enabled: () => computeEnabled()`.
- Unwrap framework signals before passing: `enabled: signal()` for Angular/Preact signals, `enabled: get(value)` for Svelte stores.
- Type the options object strictly so TypeScript rejects non-boolean/non-function values upstream.
Example fix
// before
useQuery({ queryKey, queryFn, enabled: mySignal })
// after
useQuery({ queryKey, queryFn, enabled: () => mySignal() }) Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeEnabled(v: unknown): boolean | (() => boolean) | undefined {
if (v === undefined) return undefined
if (typeof v === 'boolean') return v
if (typeof v === 'function') return v as () => boolean
throw new Error('enabled must be boolean, () => boolean, or undefined')
} Type guard
const isValidEnabled = (v: unknown): v is boolean | (() => boolean) | undefined => v === undefined || typeof v === 'boolean' || typeof v === 'function'
Prevention
- Always unwrap framework signals before passing to `enabled`.
- Coerce environment-derived flags with `Boolean()`.
- Type options strictly so non-boolean/non-function values are rejected at compile time.
- Add a test that passes each valid `enabled` shape and one invalid value.
When it happens
Trigger: Passing `enabled: 'yes'`, `enabled: 1`, `enabled: someSignalObject` (where the signal is not a function), `enabled: { default: true }`, or a `Promise<boolean>`; spreading a config where `enabled` came from an untyped JSON source.
Common situations: Bridging Angular signals/Preact signals into `enabled` without unwrapping; passing a truthy non-boolean from a form field; receiving `enabled` from a query string or environment variable as a string; refactor that changed a boolean prop to an object.
Related errors
- No QueryClient found
- No QueryClient found
- Bad argument type. Starting with v5, only the "Object" form
- argument is not function.
- ${this.queryHash} data is undefined
AI-assisted analysis of TanStack/query@159982c80b (2026-08-12).
Data as JSON: /api/errors/f150ca11cd60d07e.
Report an issue: GitHub.