{"record":{"id":"21ce25ed83051998","repo":"n8n-io/n8n","slug":"renamekeys-expected-an-even-amount-of-args-fro","errorCode":null,"errorMessage":"renameKeys(): expected an even amount of args: from1, to1 [, from2, to2, ...]. e.g. .renameKeys(\"name\", \"title\")","messagePattern":"renameKeys\\(\\): expected an even amount of args: from1, to1 \\[, from2, to2, \\.\\.\\.\\]\\. e\\.g\\. \\.renameKeys\\(\"name\", \"title\"\\)","errorType":"exception","errorClass":"ExpressionExtensionError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/expression-runtime/src/extensions/array-extensions.ts","lineNumber":191,"sourceCode":"\t\treturn o;\n\t}, {});\n}\n\nfunction chunk(value: unknown[], extraArgs: number[]) {\n\tconst [chunkSize] = extraArgs;\n\tif (typeof chunkSize !== 'number' || chunkSize === 0) {\n\t\tthrow new ExpressionExtensionError('chunk(): expected non-zero numeric arg, e.g. .chunk(5)');\n\t}\n\tconst chunks: unknown[][] = [];\n\tfor (let i = 0; i < value.length; i += chunkSize) {\n\t\tchunks.push(value.slice(i, i + chunkSize));\n\t}\n\treturn chunks;\n}\n\nfunction renameKeys(value: unknown[], extraArgs: string[]): unknown[] {\n\tif (extraArgs.length === 0 || extraArgs.length % 2 !== 0) {\n\t\tthrow new ExpressionExtensionError(\n\t\t\t'renameKeys(): expected an even amount of args: from1, to1 [, from2, to2, ...]. e.g. .renameKeys(\"name\", \"title\")',\n\t\t);\n\t}\n\treturn value.map((v) => {\n\t\tif (typeof v !== 'object' || v === null) {\n\t\t\treturn v;\n\t\t}\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any\n\t\tconst newObj = { ...(v as any) };\n\t\tconst chunkedArgs = chunk(extraArgs, [2]) as string[][];\n\t\tchunkedArgs.forEach(([from, to]) => {\n\t\t\tif (from in newObj) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\tnewObj[to] = newObj[from];\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\tdelete newObj[from];\n\t\t\t}\n\t\t});","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/expression-runtime/src/extensions/array-extensions.ts#L173-L209","documentation":"Thrown as ExpressionExtensionError by the .renameKeys() array extension when extraArgs is empty or has an odd length. renameKeys takes key pairs (from1,to1,from2,to2,...) and renames matching keys on each object in the array; an odd count means one 'from' has no matching 'to', so the call is ambiguous and rejected.","triggerScenarios":"Calling .renameKeys() with zero arguments, or an odd number of arguments. Examples: [...].renameKeys() (empty), [...].renameKeys('name') (one arg, odd), [...].renameKeys('a','b','c') (three args, odd).","commonSituations":"Forgetting the second half of a pair. Building the args list dynamically and dropping one element. Copy-paste error leaving a dangling 'from' without a 'to'.","solutions":["Pass arguments in pairs: .renameKeys('name','title').","For multiple renames, keep the count even: .renameKeys('name','title','age','years').","If building args dynamically, assert args.length % 2 === 0 before calling.","Check that template-expanded argument lists didn't drop a value."],"exampleFix":"// before — odd number of args\n{{ $json.rows.renameKeys('name', 'title', 'age') }}\n// after — even number of args (pairs)\n{{ $json.rows.renameKeys('name', 'title', 'age', 'years') }}","handlingStrategy":"validation","validationCode":"function renameKeysSafe(arr, ...pairs) {\n  if (pairs.length === 0 || pairs.length % 2 !== 0) {\n    throw new TypeError('renameKeys requires an even number of args: from1, to1, ...');\n  }\n  // ...proceed\n}","typeGuard":"function hasEvenNonEmptyArgs(args) { return Array.isArray(args) && args.length > 0 && args.length % 2 === 0; }","tryCatchPattern":"try {\n  result = arr.renameKeys('name', 'title');\n} catch (e) {\n  if (e.name === 'ExpressionExtensionError' && /renameKeys/i.test(e.message)) {\n    // supply args in pairs: from1, to1 [, from2, to2, ...]\n  }\n}","preventionTips":["Pass arguments in pairs: .renameKeys('name','title').","Assert args.length % 2 === 0 before calling.","When building the arg list dynamically, verify no element was dropped.","Test with the documented example first."],"tags":["expression-runtime","array-extensions","renamekeys","argument-validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}