redis/node-redis · error · Error
Cannot split ${label}: key region overruns the arguments
Error message
Cannot split ${label}: key region overruns the arguments What it means
The computed key region [keyRegionStart, keyRegionEnd) must lie within the actual args: keyRegionStart >= 1 (must skip the command name) and keyRegionEnd <= args.length. If the region overruns the args array — typically because a keynum spec's numkeys claims more key groups than were supplied — the splitter refuses rather than read past the end. For keynum specs this is a user-argument error (numkeys too large); for range specs the region is args.length-bounded by construction so this is harder to hit.
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 bb5beb5657)
Solutions
- For keynum commands, pass a numkeys that exactly matches the number of key groups supplied.
- Use the typed command API so the argument count is validated before routing.
- Re-check metadata beginSearch.index if the spec itself is wrong.
Example fix
// before — numkeys '3' but only one key/value group supplied
await cluster.sendCommand(['MSEDEX', '3', '{a}1', 'v1', 'NX', 'EX', '10']);
// throws: Cannot split MSEDEX: key region overruns the arguments
// after — numkeys matches the supplied groups
await cluster.sendCommand(['MSEDEX', '1', '{a}1', 'v1', 'NX', 'EX', '10']); Defensive patterns
Strategy: validation
Validate before calling
// For keynum-spec multi_shard commands, ensure numkeys matches the supplied groups.
function buildKeynumCommand(name: string, groups: Array<[string, string]>, opts: string[]) {
const flat = groups.flat();
const numkeys = groups.length;
if (!Number.isInteger(numkeys) || numkeys < 1) throw new TypeError('at least one key group required');
return [name, String(numkeys), ...flat, ...opts];
}
const args = buildKeynumCommand('MSEDEX', [['{a}1', 'v1']], ['NX', 'EX', '10']);
// args.length will always exceed the computed keyRegionEnd
await cluster.sendCommand(args); Try / catch
try {
await cluster.sendCommand(['MSEDEX', numkeys, ...keyGroups, 'NX', 'EX', '10']);
} catch (e) {
if (/key region overruns/.test(e.message)) {
// numkeys larger than supplied groups — fix the count
} else throw e;
} Prevention
- For keynum commands, pass a numkeys that exactly matches the number of key groups supplied.
- Derive numkeys from the key array length rather than hardcoding a count.
- Prefer the typed command API so argument counts are validated before routing.
When it happens
Trigger: Issuing a keynum-spec multi_shard command with numkeys larger than the supplied key groups (e.g. MSEDEX '3' with only one key/value pair), causing keyRegionEnd = firstKey + numkeys*keyStep to exceed args.length. For range specs, only reachable via a spec whose beginSearch.index is past the end of a very short arg list.
Common situations: A caller passing a numkeys count larger than the actual key groups on a keynum command; a truncated command buffer; a metadata spec with a wrong beginSearch.index.
Related errors
- Cannot split ${label}: malformed numkeys argument '${args[ke
- Cannot split ${label}: command has no key specification
- Cannot split ${label}: multiple key specifications are not s
- Cannot split ${label}: unsupported begin_search type '${begi
- Cannot split ${label}: unsupported find_keys range (lastkey
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/9e168e803158da59.json.
Report an issue: GitHub.