{"record":{"id":"e0842b844a723058","repo":"redis/node-redis","slug":"empty-keyvaluepairs-argument","errorCode":null,"errorMessage":"empty keyValuePairs Argument","messagePattern":"empty keyValuePairs Argument","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/lib/commands/MSETEX.ts","lineNumber":62,"sourceCode":"\ntype SetConditionOption = typeof SetMode.XX | typeof SetMode.NX;\n\ntype ExpirationOption =\n  | { type: typeof ExpirationMode.EX; value: number }\n  | { type: typeof ExpirationMode.PX; value: number }\n  | { type: typeof ExpirationMode.EXAT; value: number | Date }\n  | { type: typeof ExpirationMode.PXAT; value: number | Date }\n  | { type: typeof ExpirationMode.KEEPTTL };\n\nexport function parseMSetExArguments(\n  parser: CommandParser,\n  keyValuePairs: MSetArguments\n) {\n  let tuples: Array<[RedisArgument, RedisArgument]> = [];\n\n  if (Array.isArray(keyValuePairs)) {\n    if (keyValuePairs.length == 0) {\n      throw new Error(\"empty keyValuePairs Argument\");\n    }\n    if (Array.isArray(keyValuePairs[0])) {\n      tuples = keyValuePairs as Array<[RedisArgument, RedisArgument]>;\n    } else {\n      const arr = keyValuePairs as Array<RedisArgument>;\n      for (let i = 0; i < arr.length; i += 2) {\n        tuples.push([arr[i], arr[i + 1]]);\n      }\n    }\n  } else {\n    for (const tuple of Object.entries(keyValuePairs)) {\n      tuples.push([tuple[0], tuple[1]]);\n    }\n  }\n\n  // Push the number of keys\n  parser.push(tuples.length.toString());\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/commands/MSETEX.ts#L44-L80","documentation":"parseMSetExArguments rejects an empty array argument for MSETEX. MSETEX requires at least one key-value pair to be meaningful; an empty array is rejected client-side before sending a malformed command to the server.","triggerScenarios":"Calling client.msetEx([]) or passing an empty Record to the keyValuePairs parameter.","commonSituations":"Same as MSET — dynamically built collection from a data source that returned no results; batching logic producing zero entries.","solutions":["Guard with a length check before calling msetEx","Return early when the key-value collection is empty","Validate Object.keys(obj).length > 0 for Record inputs"],"exampleFix":"// before\nawait client.msetEx(pairs, opts);\n// after\nif (pairs.length > 0) {\n  await client.msetEx(pairs, opts);\n}","handlingStrategy":"validation","validationCode":"// Guard against empty collections before calling msetEx.\nfunction hasKvEntries(data: unknown): boolean {\n  if (Array.isArray(data)) return data.length > 0;\n  if (typeof data === 'object' && data !== null) return Object.keys(data).length > 0;\n  return false;\n}\n\nif (hasKvEntries(pairs)) {\n  await client.msetEx(pairs, opts);\n}","typeGuard":"function isNonEmptyRecord(obj: Record<string, unknown>): obj is Record<string, unknown> {\n  return Object.keys(obj).length > 0;\n}","tryCatchPattern":null,"preventionTips":["Check collection size before calling msetEx","Return early from the caller when the data source yields no entries","Validate Record inputs with Object.keys().length > 0"],"tags":["command","validation","arguments","msetex"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}