redis/node-redis · error · Error
Unsupported reply type for merge aggregation
Error message
Unsupported reply type for merge aggregation
What it means
The `agg_merge` reducer (default-keyless/special fallback for fan-out replies, e.g. KEYS under all_shards) merges replies only when the first reply is an Array, a Map, or a plain object. If the first reply is none of these (e.g. a scalar string, number, or null), it cannot merge and throws. Merge is last-node-wins per key for objects/Maps, union for arrays.
Source
Thrown at packages/client/lib/cluster/request-response-policies/generic-aggregators.ts:196
for(const reply of replies) {
for(const [key, value] of reply as Map<unknown, unknown>) {
map.set(key, value);
}
}
return map as T;
}
// RESP3 map replies decode to plain objects under the default type
// mapping; merge them like the Map branch (last node wins per key).
if(typeof firstReply === 'object' && firstReply !== null) {
const merged: Record<string, unknown> = {};
for(const reply of replies) {
Object.assign(merged, reply);
}
return merged as T;
}
throw new Error('Unsupported reply type for merge aggregation');
};
View on GitHub (pinned to bb5beb5657)
Solutions
- Check whether the command should really fan out — scalar-reply commands usually want default-keyed single-target routing.
- Inspect the first node's reply shape directly to see why it is not a collection.
- Provide a command-specific SPECIAL_RESPONSE_REDUCER if you are extending metadata for a fan-out scalar command.
Defensive patterns
Strategy: try-catch
Type guard
function isMergeable(reply: unknown): reply is Array<unknown> | Map<unknown, unknown> | Record<string, unknown> {
return Array.isArray(reply) || reply instanceof Map || (typeof reply === 'object' && reply !== null);
} Try / catch
try {
await cluster.sendCommand(['KEYS', '*']);
} catch (e) {
if (/Unsupported reply type for merge/.test(e.message)) {
// first shard reply was a scalar — command may not be a real fan-out candidate
} else throw e;
} Prevention
- Confirm a command should fan out before relying on merge reduction — scalar replies don't merge.
- Provide a command-specific reducer if you extend metadata for a fan-out scalar command.
- Inspect the first node's reply shape directly when merge fails.
When it happens
Trigger: A fan-out command whose response policy reduces via aggregateMerge (e.g. default-keyless fan-out like KEYS across all_shards) where the first node's reply is a scalar rather than a collection. With multiple shards returning scalars there is no defined merge.
Common situations: Issuing a command whose reply is scalar but whose policy fans out (custom override, or a special-policy command without a dedicated reducer falling back to merge); a node returning a scalar where a collection was expected.
Related errors
- All replies must be array of numbers for logical AND aggrega
- All replies must be array of numbers for logical OR aggregat
- All replies must be number arrays of equal length for ${labe
- All replies must be numbers for min aggregation
- All replies must be numbers for max aggregation
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/7a461a85f2979dde.json.
Report an issue: GitHub.