redis/node-redis · error · Error

Cannot split : unsupported find_keys type

Error message

Cannot split ${label}: unsupported find_keys type '${findKeys.type}'

What it means

Thrown by the cluster multi-shard splitter when a command's key specification declares a find_keys type other than 'range' or 'keynum'. The splitter needs to know the exact key layout to safely split a multi-key write across shards; an unknown find_keys type makes deterministic splitting impossible, so it refuses rather than risk corrupting data. No shipped multi_shard command currently reaches this branch.

Solutions

  1. File a bug against node-redis — this guard fires on library metadata, not user input
  2. If using a custom module command, verify its COMMAND DOCS output declares range or keynum find_keys
  3. Avoid routing the affected command through the cluster multi-shard path by using sendCommand or a single-node route
Defensive patterns

Strategy: try-catch

Try / catch

// Wrap cluster commands in try-catch; if this fires it's a library metadata bug.
try {
  await client.del('key1', 'key2');
} catch (e) {
  if (e.message.startsWith('Cannot split')) {
    // Report to node-redis maintainers; avoid this command in cluster mode
  }
}

Prevention

When it happens

Trigger: A command registered as multi_shard in command-metadata whose KeySpec.findKeys.type is neither 'range' nor 'keynum'. Only reachable via custom module commands with exotic key specs or a library metadata regression.

Common situations: Using a custom Redis module command marked multi_shard with an unrecognized find_keys spec; a library bug after upgrading where command metadata is corrupted.

Related errors


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

Appendix: source

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

      keyRegionEnd = args.length;
      break;
    }
    case 'keynum': {
      keyStep = findKeys.keyStep;
      keyNumIdx = start + findKeys.keyNumIdx;
      keyRegionStart = start + findKeys.firstKey;
      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);

View on GitHub (pinned to 90fd0652bc)