{"record":{"id":"cae33d9044f48440","repo":"TanStack/query","slug":"bad-argument-type-starting-with-v5-only-the-obj","errorCode":null,"errorMessage":"Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object","messagePattern":"Bad argument type\\. Starting with v5, only the \"Object\" form is allowed when calling query related functions\\. Please use the error stack to find the culprit call\\. More info here: https://tanstack\\.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/preact-query/src/useBaseQuery.ts","lineNumber":46,"sourceCode":"  TQueryFnData,\n  TError,\n  TData,\n  TQueryData,\n  TQueryKey extends QueryKey,\n>(\n  options: UseBaseQueryOptions<\n    TQueryFnData,\n    TError,\n    TData,\n    TQueryData,\n    TQueryKey\n  >,\n  Observer: typeof QueryObserver,\n  queryClient?: QueryClient,\n): QueryObserverResult<TData, TError> {\n  if (process.env.NODE_ENV !== 'production') {\n    if (typeof options !== 'object' || Array.isArray(options)) {\n      throw new Error(\n        'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n      )\n    }\n  }\n\n  const isRestoring = useIsRestoring()\n  const errorResetBoundary = useQueryErrorResetBoundary()\n  const client = useQueryClient(queryClient)\n  const defaultedOptions = client.defaultQueryOptions(options)\n\n  ;(client.getDefaultOptions().queries as any)?._experimental_beforeQuery?.(\n    defaultedOptions,\n  )\n\n  if (process.env.NODE_ENV !== 'production') {\n    if (!defaultedOptions.queryFn) {\n      console.error(\n        `[${defaultedOptions.queryHash}]: No queryFn was passed as an option, and no default queryFn was found. The queryFn parameter is only optional when using a default queryFn. More info here: https://tanstack.com/query/latest/docs/framework/react/guides/default-query-function`,","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/TanStack/query/blob/159982c80b844487054155c38ffc760fe4208daf/packages/preact-query/src/useBaseQuery.ts#L28-L64","documentation":"Dev-only runtime guard in Preact Query's `useBaseQuery`. In v5 the hooks accept exactly one `options` object; the v4 positional overloads (`useQuery(key, fn, options)`) were removed. If `options` is not a plain object, or is an array (e.g. a query key was passed directly), the hook throws before touching the observer. It only fires when `NODE_ENV !== 'production'`.","triggerScenarios":"Calling `useQuery(['todos'], fetchTodos)` (v4 positional form) under v5; passing a query-key array as the first argument; passing `null`/`undefined`/a primitive; partial migration that left some call sites in the old signature.","commonSituations":"Upgrading `@tanstack/react-query`/`@tanstack/preact-query` from v4 to v5 without running the `remove-overloads` codemod; copy-pasting v4 example code into a v5 project; a wrapper hook that forwards `...args` positionally.","solutions":["Convert the call to the single-object signature: `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })`.","Run the v5 remove-overloads codemod against the affected files: `npx @tanstack/query-codemods remove-overloads --file src/...`.","Search the codebase for `useQuery(`, `useInfiniteQuery(`, `useMutation(` and audit each to confirm it passes one object.","If a custom wrapper forwards args, refactor it to accept and spread an options object."],"exampleFix":"// before\nconst { data } = useQuery(['todos'], fetchTodos)\n// after\nconst { data } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos })","handlingStrategy":"type-guard","validationCode":"function assertQueryOptionsObject(options: unknown) {\n  if (options === null || typeof options !== 'object' || Array.isArray(options)) {\n    throw new TypeError('useQuery expects a single options object in v5')\n  }\n}","typeGuard":"const isPlainOptionsObject = (v: unknown): v is Record<string, unknown> =>\n  v !== null && typeof v === 'object' && !Array.isArray(v)","tryCatchPattern":"// Wrap legacy call sites in a compatibility shim while migrating.\nfunction safeUseQuery(arg: any, fn?: any, rest?: any) {\n  if (Array.isArray(arg)) return useQuery({ queryKey: arg, queryFn: fn, ...(rest || {}) })\n  if (typeof arg === 'string') return useQuery({ queryKey: [arg], queryFn: fn, ...(rest || {}) })\n  return useQuery(arg)\n}","preventionTips":["Run the `remove-overloads` codemod immediately after upgrading to v5.","Enable strict TypeScript checks so positional misuse is flagged at compile time.","Add an ESLint rule banning multi-arg `useQuery(` calls.","Audit wrapper hooks to forward a single options object."],"tags":["preact","v5-migration","api-contract","validation"],"backgroundTag":null,"analyzedSha":"159982c80b844487054155c38ffc760fe4208daf","analyzedAt":"2026-08-12T16:21:52.822Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}