redis/node-redis · error · Error

Cannot split : key region overruns the arguments

Error message

Cannot split ${label}: key region overruns the arguments

What it means

The computed key region (the span of arguments holding keys) extends beyond the actual argument list. For a command like MSET the splitter expects keys starting at index 1 through the end of args; if args are too short the region overruns and the split is rejected to avoid reading undefined positions.

Solutions

  1. Use the typed API (client.mSet, client.del) instead of sendCommand for compile-time argument validation
  2. If using sendCommand, verify args.length is sufficient for the command's key region before sending
  3. Add a defensive length check: for MSET ensure at least 2 args after the command name

Example fix

// before
await client.sendCommand(['MSET', 'key1']);
// after
await client.mSet({ key1: 'value1' });
Defensive patterns

Strategy: validation

Validate before calling

// For MSET-style flat arrays: ensure at least one key-value pair.
function validateMSetArgs(args: unknown[]): void {
  if (args.length < 2) {
    throw new RangeError('MSET requires at least one key-value pair (2 args)');
  }
}

Type guard

function hasMinArgs(args: unknown[], min: number): boolean {
  return Array.isArray(args) && args.length >= min;
}

Prevention

When it happens

Trigger: Calling a multi_shard command (DEL, UNLINK, EXISTS, TOUCH, MGET, MSET) via sendCommand with raw arguments that are too short, e.g. sendCommand('MSET','key1') where MSET expects at least a key and value at index 1.

Common situations: Building command arguments dynamically and accidentally truncating them; using sendCommand with raw args instead of the typed API in cluster mode; off-by-one when slicing an argument array.

Related errors


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

Appendix: source

Thrown at packages/client/lib/cluster/request-response-policies/multi-shard-splitter.ts:105

      if (keyNumIdx >= keyRegionStart) {
        throw new Error(`Cannot split ${label}: numkeys argument inside the key region`);
      }
      const numKeys = parsePositiveInteger(args[keyNumIdx]);
      if (numKeys === undefined) {
        throw new Error(`Cannot split ${label}: malformed numkeys argument '${args[keyNumIdx]}'`);
      }
      keyRegionEnd = keyRegionStart + numKeys * keyStep;
      break;
    }
    default:
      throw new Error(`Cannot split ${label}: unsupported find_keys type '${findKeys.type}'`);
  }

  if (keyStep < 1) {
    throw new Error(`Cannot split ${label}: invalid keystep ${keyStep}`);
  }
  if (keyRegionStart < 1 || keyRegionEnd > args.length) {
    throw new Error(`Cannot split ${label}: key region overruns the arguments`);
  }
  const regionLength = keyRegionEnd - keyRegionStart;
  if (regionLength <= 0 || regionLength % keyStep !== 0) {
    throw new Error(`Cannot split ${label}: key region does not align with keystep ${keyStep}`);
  }

  const groupCount = regionLength / keyStep;
  const slotGroups = new Map<number, Array<number>>();
  for (let group = 0; group < groupCount; group++) {
    const slot = calculateSlot(args[keyRegionStart + group * keyStep]);
    const groups = slotGroups.get(slot);
    if (groups) {
      groups.push(group);
    } else {
      slotGroups.set(slot, [group]);
    }
  }

View on GitHub (pinned to 90fd0652bc)