TanStack/query · warning · UnknownUsageError
The usage in file "${filePath}" at line ${start}:${end} coul
Error message
The usage in file "${filePath}" at line ${start}:${end} could not be transformed into the new syntax. Please do this manually. What it means
Thrown by the v5 `remove-overloads` codemod (UnknownUsageError) when it cannot statically resolve the binding for an identifier passed as a query/mutation key during the v4 -> v5 transform. The codemod found the call site but could not infer what value the identifier refers to (e.g. it is imported, computed, or has an unhandled shape), so it aborts that call and asks the developer to migrate it by hand. It is a build/migration-time error from `@tanstack/query-codemods`, not a runtime error of TanStack Query.
Source
Thrown at packages/query-codemods/src/v5/remove-overloads/utils/index.cjs:47
const scope = path.scope.declares(argumentName)
? path.scope
: path.scope.lookup(argumentName)
/**
* The declaration couldn't be found for some reason, time to move on. We warn the user it needs to be rewritten
* by themselves.
*/
if (!scope) {
return undefined
}
const binding = scope.bindings[argumentName]
.filter((item) => utils.isIdentifier(item.value))
.map((item) => item.parentPath.value)
.at(0)
if (!binding) {
throw new UnknownUsageError(path.node, filePath)
}
return binding
}
/**
* @param {import('jscodeshift').VariableDeclarator} binding
* @returns {import('jscodeshift').Node|undefined}
*/
const getInitializerByDeclarator = (binding) => {
const isVariableDeclaration = jscodeshift.match(binding, {
type: jscodeshift.VariableDeclarator.name,
})
if (!isVariableDeclaration) {
return undefined
}
View on GitHub (pinned to 159982c80b)
Solutions
- Open the file and line reported in the error message and manually convert the call to the v5 object syntax, e.g. `useQuery({ queryKey: myKey, queryFn })`.
- If the key is imported from another module, inline it or restructure so the codemod can see a local array declaration, then re-run the transform.
- Re-run the codemod with `--dry` to preview remaining call sites and confirm how many still fail before committing.
- Upgrade `@tanstack/query-codemods` to the latest version — later releases handle more binding shapes (TSAsExpression, ArrayExpression, etc.).
Example fix
// before (v4) - myKey is imported, codemod cannot resolve it
import { myKey } from './keys'
useQuery(myKey, fetchTodos)
// after (v5) - wrap in object manually
import { myKey } from './keys'
useQuery({ queryKey: myKey, queryFn: fetchTodos }) Defensive patterns
Strategy: try-catch
Validate before calling
// Before running the codemod, grep for patterns the codemod cannot resolve
const fs = require('fs')
const src = fs.readFileSync(filePath, 'utf8')
// Heuristic: query/mutation calls whose first arg is a bare identifier that is imported
const suspicious = [...src.matchAll(/\b(?:useQuery|useMutation|useInfiniteQuery)\s*\(\s*([A-Za-z_$][\w$]*)\s*,/g)]
.map(m => m[1])
.filter(name => /^import\b[^;]*\b${name}\b/m.test(src))
console.log(suspicious.length ? `Review manually: ${suspicious.join(', ')}` : 'OK') Type guard
// The codemod's own predicate - mirror it to predict failures const isResolvableBinding = (bindingItems, utils) => bindingItems.some((item) => utils.isIdentifier(item.value))
Try / catch
// Wrap the codemod transform so one unresolvable call does not abort the file
try {
await runCodemod(file)
} catch (e) {
if (e.name === 'UnknownUsageError') {
console.warn(`Manual migration needed: ${e.message}`)
pendingManual.add(file)
} else {
throw e
}
} Prevention
- Keep query keys as local array literals (`const todosKey = ['todos']`) so the codemod can see the ArrayExpression binding.
- Run the codemod with --dry first to enumerate failures before mutating files.
- Upgrade @tanstack/query-codemods to the latest release before migrating.
- For shared key factories, inline or localise the keys during migration, then refactor back afterwards.
When it happens
Trigger: Running `npx @tanstack/query-codemods@latest` (or the v5 `remove-overloads` transform specifically) against a source file where a Query/Mutation method's first argument is an identifier whose binding is not an `Identifier`-typed AST node the codemod recognises — e.g. `useQuery(myKey, fn)` where `myKey` is imported from another module, generated by a function call, spread from another object, or declared with a non-standard pattern. Triggered when `scope.bindings[argumentName]` exists but none of the items pass `utils.isIdentifier(item.value)`, so `binding` is `undefined`.
Common situations: Migrating a large codebase to TanStack Query v5 where query keys are exported from a shared `queryKeys.ts` factory module, defined via a key builder function (`todoKeys.list()`), imported across files, or constructed with `as const` inside another variable. Also occurs with monorepo setups where the codemod runs per-file and cannot see cross-package bindings.
Related errors
- In file ${filePath} at line ${node.loc.start.line} the type
- In file ${filePath} at line ${node.loc.start.line} the type
- In file ${filePath} at line ${node.loc.start.line} the \`${k
- The usage in file "${filePath}" at line ${start}:${end} coul
- The usage in file "${filePath}" at line ${start}:${end} coul
AI-assisted analysis of TanStack/query@159982c80b (2026-08-12).
Data as JSON: /api/errors/c7415997986dba13.
Report an issue: GitHub.