redis/node-redis · error · Error
Cannot split : invalid keystep
Error message
Cannot split ${label}: invalid keystep ${keyStep} What it means
Thrown by the multi-shard splitter when the keyStep value extracted from a command's key specification is less than 1. keyStep defines how many arguments each key group spans (e.g., MSET has keyStep 2: key + value). A step of 0 or negative is structurally invalid and would cause an infinite loop or divide-by-zero in the grouping logic.
Solutions
- Report the bug to node-redis maintainers with the command name and version
- Verify custom module command key specs declare keyStep >= 1
- Work around by avoiding the cluster multi-shard routing path for the affected command
Defensive patterns
Strategy: try-catch
Try / catch
// This guard fires on library metadata bugs, not user input.
try {
await client.mSet(pairs);
} catch (e) {
if (e.message.includes('invalid keystep')) {
// Library metadata regression — report the issue
}
} Prevention
- Pin to a stable node-redis release
- Run integration tests against the cluster after library upgrades
- Report metadata issues with the command name and library version
When it happens
Trigger: A multi_shard command's KeySpec declares keyStep < 1. This is a metadata bug — no shipped command has this value.
Common situations: Library regression after updating command metadata definitions; custom module command with an incorrect key specification.
Related errors
- Cannot split : unsupported find_keys type
- Cannot split : command has no key specification
- Cannot split : key region does not align with keystep
- Cannot split : key region overruns the arguments
- Cannot split : malformed numkeys argument
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/e12d0dc92cd7697e.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/cluster/request-response-policies/multi-shard-splitter.ts:102
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);
if (groups) {
groups.push(group);
} else {
slotGroups.set(slot, [group]);View on GitHub (pinned to 90fd0652bc)