redis/node-redis · error · Error
Cannot split : key region does not align with keystep
Error message
Cannot split ${label}: key region does not align with keystep ${keyStep} What it means
The key region length is not a positive multiple of keyStep, meaning the arguments contain an incomplete key group. For MSET (keyStep 2) a flat array with an odd number of elements leaves the last key without a value, so the splitter cannot form valid sub-commands.
Solutions
- Ensure flat arrays have even length for key-value pair commands (MSET keyStep is 2)
- Use tuple arrays [[key, value], ...] or Record objects for type safety instead of flat arrays
- Validate before sending: arr.length % keyStep === 0
Example fix
// before await client.mSet(['key1', 'val1', 'key2']); // after await client.mSet(['key1', 'val1', 'key2', 'val2']);
Defensive patterns
Strategy: validation
Validate before calling
// For flat key-value arrays: ensure even length (keyStep is 2 for MSET).
function isBalancedKvArray(arr: unknown[]): boolean {
return arr.length > 0 && arr.length % 2 === 0;
}
if (!isBalancedKvArray(pairs)) {
throw new Error('Flat MSET array must have an even number of elements');
} Type guard
function isEvenLength(arr: Array<unknown>): arr is Array<unknown> & { length: number } {
return arr.length % 2 === 0;
} Prevention
- Use tuple arrays [[key, value], ...] or Record objects instead of flat arrays
- Validate arr.length % 2 === 0 before calling mSet with a flat array
- Build key-value pairs in a loop that always pushes both key and value together
When it happens
Trigger: Calling client.mSet(['key1','value1','key2']) in cluster mode — 3 elements with keyStep 2 leaves 'key2' without a value. Also triggered by any flat-array multi-key command with an unbalanced argument count.
Common situations: Dynamically building a flat key-value array and omitting a value; an off-by-one in a loop that constructs pairs; data source returning an odd number of fields.
Related errors
- Cannot split : key region overruns the arguments
- "arguments[ ]" must be of type "string | Buffer", got…
- Cannot split : command has no key specification
- Cannot split : invalid keystep
- Cannot split : malformed numkeys argument
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/3295b573beb013fb.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/cluster/request-response-policies/multi-shard-splitter.ts:109
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]);
}
}
const subCommands = new Map<number, SubCommand>();
// Single-slot fast path: nothing to split — pass the original command
// through untouched (also preserves single-slot atomicity). Keys keep theirView on GitHub (pinned to 90fd0652bc)