redis/node-redis · error · Error
Cannot split ${label}: command has no key specification
Error message
Cannot split ${label}: command has no key specification What it means
splitMultiShardCommand refuses to split a multi_shard command whose COMMAND key specification is missing or empty. Without a key spec the splitter cannot locate the key region to partition per slot, and a wrong split of a write command would corrupt data — so it throws deterministically. All current multi_shard commands (DEL, UNLINK, EXISTS, TOUCH, MGET, MSET) declare exactly one spec; hitting this means the metadata is malformed for a multi_shard-tagged command.
Source
Thrown at packages/client/lib/cluster/request-response-policies/multi-shard-splitter.ts:46
* relative order) + suffix; for `keynum` specs the numkeys argument in the
* prefix is rewritten to the sub-command's group count.
*
* Throws on anything it cannot split deterministically — a wrong split of a
* write command means corrupted data, so refusal beats guessing. All current
* multi_shard commands (DEL, UNLINK, EXISTS, TOUCH, MGET, MSET) declare
* exactly one supported spec. MSETEX is curated OUT of multi_shard
* (command-metadata-overrides.ts): its NX/XX condition is all-or-nothing
* across all keys and cannot be evaluated per shard — it routes default-keyed
* like MSETNX, so the keynum branch below currently has no live caller.
*/
export function splitMultiShardCommand(
args: ReadonlyArray<RedisArgument>,
keySpecs: ReadonlyArray<KeySpec> | undefined
): Map<number, SubCommand> {
const label = args.length > 0 ? args[0].toString() : '<empty>';
if (!keySpecs || keySpecs.length === 0) {
throw new Error(`Cannot split ${label}: command has no key specification`);
}
// TODO(multi-spec): a command whose keys are interchangeable but
// syntactically scattered (e.g. a fixed-position key plus a keyword-tail
// list) could legitimately be multi_shard with several specs, and
// multi-region reconstruction would be deterministic. No such command
// exists, and specs alone cannot distinguish that shape from linked-operand
// specs (GEORADIUS-like) where splitting is meaningless — so refuse until a
// real command motivates multi-region support.
if (keySpecs.length > 1) {
throw new Error(`Cannot split ${label}: multiple key specifications are not supported`);
}
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;View on GitHub (pinned to bb5beb5657)
Solutions
- Check command-metadata overrides for the offending command — multi_shard requires a populated keySpecs.
- Re-run metadata generation against a Redis version that reports key specs for the command.
- If the command genuinely has no key spec, it is not multi_shard — change its request policy to default-keyed or default-keyless.
Defensive patterns
Strategy: try-catch
Type guard
function hasKeySpec(specs: unknown): specs is Array<{ beginSearch: object; findKeys: object }> {
return Array.isArray(specs) && specs.length > 0;
} Try / catch
try {
await cluster.del('k1', 'k2');
} catch (e) {
if (/no key specification/.test(e.message)) {
// metadata for this multi_shard command is malformed — regenerate or override
} else throw e;
} Prevention
- After regenerating command metadata, verify multi_shard commands carry populated keySpecs.
- Audit command-metadata overrides before assigning multi_shard.
- If a command has no key spec, route it default-keyed/default-keyless instead.
When it happens
Trigger: A command tagged `multi_shard` in the metadata whose keySpecs array is undefined/empty. Reachable after a metadata regeneration that tags a new command multi_shard but fails to capture its key specs, or a manual metadata override that drops keySpecs.
Common situations: Custom command-metadata override assigning multi_shard without keySpecs; a metadata regeneration bug against a Redis version that reports no key specs for the tagged command.
Related errors
- 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
- 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/271d686230926548.json.
Report an issue: GitHub.