TanStack/query · warning · UnprocessableKeyError
In file ${filePath} at line ${node.loc.start.line} the type
Error message
In file ${filePath} at line ${node.loc.start.line} the type of identifier \`${node.name}\` couldn't be recognized, so the codemod couldn't be applied. Please migrate manually. What it means
`UnprocessableKeyError` from the v4 codemod's `key-replacer.cjs`. When the AST node for a query key is an `Identifier`, the codemod tries to find its `const` declaration (`findVariableDeclaration`) to guess the type. If no declaration is found (e.g. a parameter, an import, or a destructured binding), it cannot safely transform and throws with the file path and line number for manual migration.
Source
Thrown at packages/query-codemods/src/v4/utils/replacers/key-replacer.cjs:53
return jscodeshift.arrayExpression([
jscodeshift.stringLiteral(node.value),
])
}
// When the node is a template literal we convert it into an array of template literals.
if (isTemplateLiteral(node)) {
return jscodeshift.arrayExpression([
jscodeshift.templateLiteral(node.quasis, node.expressions),
])
}
if (jscodeshift.match(node, { type: jscodeshift.Identifier.name })) {
// When the node is an identifier at first, we try to find its declaration, because we will try
// to guess its type.
const variableDeclaration = findVariableDeclaration(node)
if (!variableDeclaration) {
throw new UnprocessableKeyError(
`In file ${filePath} at line ${node.loc.start.line} the type of identifier \`${node.name}\` couldn't be recognized, so the codemod couldn't be applied. Please migrate manually.`,
)
}
const initializer = variableDeclaration.value.init
// When it's a string, we just wrap it into an array expression.
if (isStringLiteral(initializer) || isTemplateLiteral(initializer)) {
return jscodeshift.arrayExpression([node])
}
}
throw new UnprocessableKeyError(
`In file ${filePath} at line ${node.loc.start.line} the type of the \`${keyName}\` couldn't be recognized, so the codemod couldn't be applied. Please migrate manually.`,
)
}
const createKeyProperty = (node) =>View on GitHub (pinned to 159982c80b)
Solutions
- Open the cited file:line and convert the query key to a literal array or template literal so the codemod can handle it, then re-run.
- Manually wrap the identifier: `useQuery([myKey], ...)` -> `useQuery({ queryKey: [myKey], queryFn: ... })`.
- Hoist the identifier into a `const` array literal near the call site so the codemod finds its declaration.
- Re-run the codemod on the fixed file and verify other call sites still transform.
Example fix
// before
useQuery(myKey, fetchFn)
// after (manual)
useQuery({ queryKey: [myKey], queryFn: fetchFn }) Defensive patterns
Strategy: try-catch
Validate before calling
// Codemod-side: pre-scan for identifiers without findable declarations.
function hasSimpleDeclaration(scope: any, name: string): boolean {
const node = scope.lookup(name)
return !!node && node.value?.init
} Try / catch
// Drive the codemod and collect failures for manual review.
const report = []
for (const file of files) {
try { runCodemod(file) }
catch (e) { if (e.name === 'UnprocessableKeyError') report.push({ file, message: e.message }) }
} Prevention
- Simplify key identifiers to local `const` array literals before running the codemod.
- Avoid imported/parameter key bindings at query call sites during migration.
- Run the codemod per-file and collect the cited file:line for manual follow-up.
- Re-run after manual fixes to confirm transformation.
When it happens
Trigger: Running the v4 codemod on code where the query key is an identifier whose declaration is not a simple `const x = ...` in scope: function parameters, imported bindings, destructured variables, properties (`obj.key`), loop variables, or identifiers declared with `let`/`var` in a different block.
Common situations: Migrating a large v3->v4 codebase with non-trivial key indirection; codemod applied to partial files; keys computed from props/parameters in shared hooks; older codebases with `var` declarations.
Related errors
- 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
- The usage in file "${filePath}" at line ${start}:${end} alre
AI-assisted analysis of TanStack/query@159982c80b (2026-08-12).
Data as JSON: /api/errors/7009ee5a97fd29c7.
Report an issue: GitHub.