{"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/bb5beb56578573910e2ee8f39681edc214c41398/packages/client/lib/commands/MSETEX.ts#L44-L80","documentation":"Thrown by parseMSetExArguments when the keyValuePairs argument passed to MSETEX is an Array with length 0. MSETEX needs at least one key/value pair (plus optional mode/expiration); an empty payload is rejected client-side before the command is sent.","triggerScenarios":"Calling client.msetEx([]) or passing an empty array built from a filtered/empty source.","commonSituations":"Bulk-write helper invoked with no pending entries; conditional flush of an empty change set; refactor that drops the empty check.","solutions":["Skip the MSETEX call when the array is empty.","Validate the payload has at least one pair before invoking.","Build pairs from a guaranteed non-empty source."],"exampleFix":"// before\nawait client.msetEx(pairs, { mode: 'NX' }); // pairs may be []\n\n// after\nif (pairs.length > 0) await client.msetEx(pairs, { mode: 'NX' });","handlingStrategy":"validation","validationCode":"function nonEmptyMSetEx(a) { if (Array.isArray(a) && a.length === 0) throw new Error('MSETEX needs >=1 pair'); }\nnonEmptyMSetEx(pairs); await client.msetEx(pairs, opts);","typeGuard":"function hasMSetExPairs(a) { return Array.isArray(a) ? a.length > 0 : a != null && Object.keys(a).length > 0; }","tryCatchPattern":"if (hasMSetExPairs(pairs)) await client.msetEx(pairs, opts);","preventionTips":["Guard batch writes for emptiness before calling MSETEX.","Filter to pairs and assert non-empty.","Unit-test the empty-input path of write helpers."],"tags":["msetex","validation","user-error","arguments"],"analyzedSha":"bb5beb56578573910e2ee8f39681edc214c41398","analyzedAt":"2026-08-03T19:09:15.686Z","schemaVersion":2}