redis/node-redis · error · Error

Cannot split ${label}: multiple key specifications are not s

Error message

Cannot split ${label}: multiple key specifications are not supported

What it means

splitMultiShardCommand refuses commands with more than one key specification. Multiple specs could mean either interchangeable scattered keys (splittable) or linked-operand specs like GEORADIUS (not splittable), and the spec shape alone cannot distinguish them — so the splitter refuses until a real command motivates multi-spec support. No current multi_shard command declares >1 spec.

Source

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

 */
export function splitMultiShardCommand(
  args: ReadonlyArray<RedisArgument>,
  keySpecs: ReadonlyArray<KeySpec> | undefined
): Map<number, SubCommand> {
  const label = args.length > 0 ? args[0].toString() : '<empty>';

  if (!keySpecs || keySpecs.length === 0) {
    throw new Error(`Cannot split ${label}: command has no key specification`);
  }
  // TODO(multi-spec): a command whose keys are interchangeable but
  // syntactically scattered (e.g. a fixed-position key plus a keyword-tail
  // list) could legitimately be multi_shard with several specs, and
  // multi-region reconstruction would be deterministic. No such command
  // exists, and specs alone cannot distinguish that shape from linked-operand
  // specs (GEORADIUS-like) where splitting is meaningless — so refuse until a
  // real command motivates multi-region support.
  if (keySpecs.length > 1) {
    throw new Error(`Cannot split ${label}: multiple key specifications are not supported`);
  }

  const { beginSearch, findKeys } = keySpecs[0];
  if (beginSearch.type !== 'index') {
    throw new Error(`Cannot split ${label}: unsupported begin_search type '${beginSearch.type}'`);
  }

  const start = beginSearch.index;
  let keyRegionStart: number;
  let keyRegionEnd: number;
  let keyStep: number;
  // Absolute position of the numkeys argument to rewrite per sub-command.
  let keyNumIdx: number | undefined;

  switch (findKeys.type) {
    case 'range': {
      // All current multi_shard range specs are "until end of args"; bounded
      // ranges (lastKey >= 0) and limit can be added when a command needs them.

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Verify the command should be multi_shard at all — multi-spec commands are often better routed default-keyed.
  2. If splitting is genuinely required, extend splitMultiShardCommand to handle multi-region reconstruction (the TODO at multi-shard-splitter.ts:48 marks this).
  3. Re-tag the command to a supported request policy in command-metadata overrides.
Defensive patterns

Strategy: try-catch

Type guard

function isSingleSpec(specs: unknown): specs is [object] {
  return Array.isArray(specs) && specs.length === 1;
}

Try / catch

try {
  await cluster.del('k1', 'k2');
} catch (e) {
  if (/multiple key specifications/.test(e.message)) {
    // command tagged multi_shard with >1 spec — re-tag or extend the splitter
  } else throw e;
}

Prevention

When it happens

Trigger: A command tagged multi_shard whose COMMAND INFO reports two or more key specifications. Reachable only via metadata change tagging such a command, not by user arguments.

Common situations: A future/new command that Redis tags multi_shard with several specs; a metadata override that incorrectly tags a multi-spec command as multi_shard.

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/1a3c0902cd395aa9.json. Report an issue: GitHub.