{"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/bb5beb56578573910e2ee8f39681edc214c41398/packages/client/lib/RESP/encoder.ts#L3-L29","documentation":"Thrown by the RESP command encoder (encodeCommand) when iterating over command arguments: every arg must be either a string or a Buffer so it can be length-prefixed and written to the wire. If any element is a number, boolean, object, null, or undefined, the encoder cannot compute its byte length and rejects it with a TypeError naming the offending index and the actual typeof. This guards the lowest layer of the client against emitting malformed RESP.","triggerScenarios":"Calling `client.sendCommand([42])` or `client.set('k', 123)` where 123 is a number (some commands coerce, but raw sendCommand and custom commands do not). Passing an object/undefined/null as a command argument, or using `client.multi().addCommand(['GET', someObject])`. Building args from untyped JSON without stringifying numeric/boolean fields.","commonSituations":"Passing numeric counters/IDs straight from JS logic into a command; forgetting to `String()` or `.toString()` values read from JSON/env; mixing a loosely-typed data layer with the strongly-typed Redis client; writing a custom Command whose parseCommand pushes a non-coerced variable.","solutions":["Coerce each dynamic argument to a string before passing it: `String(value)` or `Buffer.from(value)`.","If the value is binary, pass it as a Buffer: `Buffer.from(value)`.","For custom commands, ensure parseCommand only ever pushes string/Buffer via parser.push / parser.pushVariadic with pre-converted values.","Validate/serialize at the boundary where untrusted JSON enters your Redis call layer."],"exampleFix":"// before\nawait client.sendCommand(['SET', 'counter', 123]);\n\n// after\nawait client.sendCommand(['SET', 'counter', String(123)]);","handlingStrategy":"validation","validationCode":"function toRedisArg(value: unknown): string | Buffer {\n  if (typeof value === 'string') return value;\n  if (Buffer.isBuffer(value)) return value;\n  throw new TypeError(`Cannot encode ${typeof value} as a Redis argument`);\n}\n// usage: client.sendCommand(['SET', 'k', toRedisArg(maybeNumber) as string]);","typeGuard":"function isRedisArgument(arg: unknown): arg is string | Buffer {\n  return typeof arg === 'string' || Buffer.isBuffer(arg);\n}","tryCatchPattern":"try {\n  await client.sendCommand(args);\n} catch (err) {\n  if (err instanceof TypeError && /must be of type/.test(err.message)) {\n    // an argument was not string|Buffer; serialize and retry, or surface a config error\n  }\n  throw err;\n}","preventionTips":["Never pass numbers/booleans/objects/raw JSON into command args without explicit String()/Buffer conversion.","Type your command-building helpers to accept only string | Buffer.","Enable strict TypeScript types so untyped values cannot reach sendCommand."],"tags":["encoding","validation","typescript"],"analyzedSha":"bb5beb56578573910e2ee8f39681edc214c41398","analyzedAt":"2026-08-03T19:09:15.686Z","schemaVersion":2}