redis/node-redis · error · Error
No slots to migrate
Error message
No slots to migrate
What it means
Internal invariant guard inside buildSMigratedNotification — the RESP encoder for the SMIGRATED push notification. It rejects an empty movedSlotsByDestination array because an SMIGRATED notification carrying zero slot-move entries is meaningless. The sole in-repo caller (triggerMigrate) always passes exactly one entry, so this is a defensive check for future callers or direct use of the helper.
Source
Thrown at packages/test-utils/lib/fault-injector/proxied-fault-injector-cluster.ts:183
return {
id,
host,
port: Number(port),
proxyPort: Number(proxyPort),
};
};
const buildSMigratedNotification = (
movedSlotsByDestination: Array<{
targetNode: { host: string; port: number };
slotRanges: string; // e.g., "0-5460" or "0-100,200-300,500"
}>,
seqId: number = 1,
encoding: "base64" | "raw" = "base64"
): string => {
if (movedSlotsByDestination.length === 0) {
throw new Error("No slots to migrate");
}
const entries = movedSlotsByDestination.map(({ targetNode, slotRanges }) => {
const hostPort = `${targetNode.host}:${targetNode.port}`;
return `*2\r\n+${hostPort}\r\n+${slotRanges}\r\n`;
});
const response = `>3\r\n+SMIGRATED\r\n:${seqId}\r\n*${
movedSlotsByDestination.length
}\r\n${entries.join("")}`;
return encoding === "raw"
? response
: Buffer.from(response).toString(encoding);
};
const buildClusterSlotsResponse = (
nodes: ProxyNode[],View on GitHub (pinned to 90fd0652bc)
Solutions
- Pass at least one { targetNode, slotRanges } entry to buildSMigratedNotification.
- If entries are computed dynamically, guard upstream and skip emitting the SMIGRATED notification entirely when there is nothing to migrate instead of calling the helper with [].
Example fix
// before
const entries = pickEntries(); // may be []
const notif = buildSMigratedNotification(entries);
// after
const entries = pickEntries();
if (entries.length === 0) return { status: 'success', error: null, output: 'Nothing to migrate' };
const notif = buildSMigratedNotification(entries); Defensive patterns
Strategy: validation
Validate before calling
function hasMigratedEntries(entries: Array<{ targetNode: { host: string; port: number }; slotRanges: string }>): boolean {
return entries.length > 0 && entries.every(e => e.slotRanges.length > 0);
}
// only call buildSMigratedNotification when hasMigratedEntries(entries) is true Type guard
const isNonEmptyEntries = (e: unknown): e is Array<{ targetNode: { host: string; port: number }; slotRanges: string }> =>
Array.isArray(e) && e.length > 0; Prevention
- Guard the caller: skip emitting SMIGRATED when the computed entries list is empty instead of forwarding [] to the helper.
- Treat an empty entries list as a no-op success upstream, not as an error path inside the encoder.
- If you reuse buildSMigratedNotification in a new scenario, add a unit test for the empty-input contract.
When it happens
Trigger: Calling buildSMigratedNotification([]) directly, or a future caller that computes the destination/slot list dynamically and passes an empty array because no slots were selected or no destination node was found.
Common situations: Refactoring triggerMigrate to build the entries list conditionally (e.g., filtering nodes) such that it can become empty; a new fault-injection scenario reusing the helper without guaranteeing at least one entry.
Related errors
- [Proxy] Failed to send SMIGRATING notification: ${migratingR
- [Proxy] No node with no connections
- [Proxy] No destination node
- [Proxy] Failed to send SMIGRATED notification: ${migratedRes
- Could not find shard
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/2b9ffd38143d45f1.
Report an issue: GitHub.