{"record":{"id":"3fdd5bd1b3b5842d","repo":"redis/node-redis","slug":"arguments-i-must-be-of-type-string-buffer","errorCode":null,"errorMessage":"\"arguments[${i}]\" must be of type \"string | Buffer\", got ${typeof arg} instead.","messagePattern":"\"arguments\\[(.+?)\\]\" must be of type \"string \\| Buffer\", got (.+?) instead\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/client/lib/RESP/encoder.ts","lineNumber":21,"sourceCode":"const CRLF = '\\r\\n';\n\nexport default function encodeCommand(args: ReadonlyArray<RedisArgument>): ReadonlyArray<RedisArgument> {\n  const toWrite: Array<RedisArgument> = [];\n\n  let strings = '*' + args.length + CRLF;\n\n  for (let i = 0; i < args.length; i++) {\n    const arg = args[i];\n    if (typeof arg === 'string') {\n      strings += '$' + Buffer.byteLength(arg) + CRLF + arg + CRLF;\n    } else if (arg instanceof Buffer) {\n      toWrite.push(\n        strings + '$' + arg.length.toString() + CRLF,\n        arg\n      );\n      strings = CRLF;\n    } else {\n      throw new TypeError(`\"arguments[${i}]\" must be of type \"string | Buffer\", got ${typeof arg} instead.`);\n    }\n  }\n\n  toWrite.push(strings);\n\n  return toWrite;\n}\n","sourceCodeStart":3,"sourceCodeEnd":29,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/RESP/encoder.ts#L3-L29","documentation":"The RESP encoder iterates command args and only accepts values of type string or Buffer. Anything else (number, boolean, undefined, null, plain object, array, Uint8Array) throws a TypeError naming the offending index. Numbers and other primitives must be stringified by the caller before reaching the encoder.","triggerScenarios":"Calling client.sendCommand([name, ...args]) with a non-string/non-Buffer arg; building args manually and leaving an optional slot as undefined; passing a Date, JSON object, or number raw; multi.addCommand(['CMD', 42, undefined]).","commonSituations":"Forgetting String(n) when assembling raw args; an optional flag left undefined; passing Uint8Array instead of Buffer; a helper returning undefined that flows into args; serializing an object with JSON.stringify forgotten.","solutions":["Stringify numbers and coerce: String(n).","Filter undefined/null out of the args array before sending.","Prefer the typed command wrappers (client.set, client.hSet, ...) which coerce arguments for you.","Convert Uint8Array to Buffer: Buffer.from(uint8)."],"exampleFix":"// before\nclient.sendCommand(['SET', 'k', 42, undefined]);\n\n// after\nclient.sendCommand(['SET', 'k', String(42)]);","handlingStrategy":"type-guard","validationCode":"function sanitizeArgs(args) {\n  const out = [];\n  for (let i = 0; i < args.length; i++) {\n    const a = args[i];\n    if (a == null) continue; // drop undefined/null\n    if (typeof a === 'string' || Buffer.isBuffer(a)) {\n      out.push(a);\n    } else if (typeof a === 'number' || typeof a === 'bigint' || typeof a === 'boolean') {\n      out.push(String(a));\n    } else if (a instanceof Uint8Array) {\n      out.push(Buffer.from(a));\n    } else {\n      throw new TypeError(`arguments[${i}] unsupported type ${typeof a}`);\n    }\n  }\n  return out;\n}\n\nclient.sendCommand(sanitizeArgs(rawArgs));","typeGuard":"function isValidArg(a) {\n  return typeof a === 'string' || Buffer.isBuffer(a);\n}\n\nfunction allValidArgs(args) {\n  return Array.isArray(args) && args.every(isValidArg);\n}","tryCatchPattern":null,"preventionTips":["Prefer typed command methods (client.set, client.hSet) over sendCommand; they coerce for you.","Always String() numbers when building raw args.","Filter undefined out of optional-arg arrays before sending.","Convert Uint8Array to Buffer explicitly."],"tags":["encoder","type-error","validation","arguments"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}