redis/node-redis · error · Error
Cannot split ${label}: unsupported find_keys range (lastkey
Error message
Cannot split ${label}: unsupported find_keys range (lastkey ${findKeys.lastKey}, limit ${findKeys.limit}) What it means
For `range` find_keys, the splitter only supports the 'until end of args' shape: lastKey === -1 and limit === 0. A bounded range (lastKey >= 0, i.e. keys occupy a fixed suffix region with trailing non-key args, or a non-zero limit/step pattern) is not implemented because no current multi_shard command needs it. The splitter refuses rather than mis-split.
Source
Thrown at packages/client/lib/cluster/request-response-policies/multi-shard-splitter.ts:76
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.
if (findKeys.lastKey !== -1 || findKeys.limit !== 0) {
throw new Error(`Cannot split ${label}: unsupported find_keys range (lastkey ${findKeys.lastKey}, limit ${findKeys.limit})`);
}
keyStep = findKeys.keyStep;
keyRegionStart = start;
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;View on GitHub (pinned to bb5beb5657)
Solutions
- Confirm the command's key region extends to end-of-args; if bounded, multi_shard split is not supported yet.
- Extend the range branch (multi-shard-splitter.ts:75) to handle bounded ranges if a real command needs it.
- Re-tag the command to default-keyed routing.
Defensive patterns
Strategy: try-catch
Type guard
function isUnboundedRange(spec: unknown): boolean {
return typeof spec === 'object' && spec !== null
&& (spec as { type?: string }).type === 'range'
&& (spec as { lastKey?: number }).lastKey === -1
&& (spec as { limit?: number }).limit === 0;
} Try / catch
try {
await cluster.del('k1', 'k2');
} catch (e) {
if (/unsupported find_keys range/.test(e.message)) {
// spec is a bounded range — re-tag command or extend the splitter
} else throw e;
} Prevention
- Only tag commands whose key region extends to end-of-args as multi_shard (range lastKey=-1, limit=0).
- Extend the range branch (multi-shard-splitter.ts:75) only if a real command needs bounded ranges.
- Audit metadata overrides for bounded-range commands.
When it happens
Trigger: A command tagged multi_shard whose range spec has lastKey >= 0 or limit !== 0. Reachable only via metadata change; current commands (DEL/UNLINK/EXISTS/TOUCH/MGET/MSET) all use lastKey=-1, limit=0.
Common situations: A future multi_shard command whose keys occupy a bounded region followed by options; a metadata override mis-tagging such a command.
Related errors
- 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}: numkeys argument inside the key regio
- Cannot split ${label}: unsupported find_keys type '${findKey
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/803ca0194d93c228.json.
Report an issue: GitHub.