redis/node-redis · error · Error

empty keyValuePairs Argument

Error message

empty keyValuePairs Argument

What it means

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.

Solutions

  1. Guard with a length check before calling msetEx
  2. Return early when the key-value collection is empty
  3. Validate Object.keys(obj).length > 0 for Record inputs

Example fix

// before
await client.msetEx(pairs, opts);
// after
if (pairs.length > 0) {
  await client.msetEx(pairs, opts);
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard against empty collections before calling msetEx.
function hasKvEntries(data: unknown): boolean {
  if (Array.isArray(data)) return data.length > 0;
  if (typeof data === 'object' && data !== null) return Object.keys(data).length > 0;
  return false;
}

if (hasKvEntries(pairs)) {
  await client.msetEx(pairs, opts);
}

Type guard

function isNonEmptyRecord(obj: Record<string, unknown>): obj is Record<string, unknown> {
  return Object.keys(obj).length > 0;
}

Prevention

When it happens

Trigger: Calling client.msetEx([]) or passing an empty Record to the keyValuePairs parameter.

Common situations: Same as MSET — dynamically built collection from a data source that returned no results; batching logic producing zero entries.

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/e0842b844a723058. Report an issue: GitHub.

Appendix: source

Thrown at packages/client/lib/commands/MSETEX.ts:62

type SetConditionOption = typeof SetMode.XX | typeof SetMode.NX;

type ExpirationOption =
  | { type: typeof ExpirationMode.EX; value: number }
  | { type: typeof ExpirationMode.PX; value: number }
  | { type: typeof ExpirationMode.EXAT; value: number | Date }
  | { type: typeof ExpirationMode.PXAT; value: number | Date }
  | { type: typeof ExpirationMode.KEEPTTL };

export function parseMSetExArguments(
  parser: CommandParser,
  keyValuePairs: MSetArguments
) {
  let tuples: Array<[RedisArgument, RedisArgument]> = [];

  if (Array.isArray(keyValuePairs)) {
    if (keyValuePairs.length == 0) {
      throw new Error("empty keyValuePairs Argument");
    }
    if (Array.isArray(keyValuePairs[0])) {
      tuples = keyValuePairs as Array<[RedisArgument, RedisArgument]>;
    } else {
      const arr = keyValuePairs as Array<RedisArgument>;
      for (let i = 0; i < arr.length; i += 2) {
        tuples.push([arr[i], arr[i + 1]]);
      }
    }
  } else {
    for (const tuple of Object.entries(keyValuePairs)) {
      tuples.push([tuple[0], tuple[1]]);
    }
  }

  // Push the number of keys
  parser.push(tuples.length.toString());

View on GitHub (pinned to 90fd0652bc)