redis/node-redis · error · Error

All replies must be numbers for sum aggregation

Error message

All replies must be numbers for sum aggregation

What it means

Thrown by aggregateSum when at least one shard's reply is not a number. Used by DBSIZE (all_shards + agg_sum), DEL/EXISTS/TOUCH/UNLINK (multi_shard + agg_sum), and several MEMORY/LATENCY subcommands. Each shard must return a scalar number to be summed.

Solutions

  1. Ensure all cluster nodes run the same Redis version
  2. Check for degraded or erroring shards
  3. Verify the typeMapping configuration — a NUMBER:String mapping is normally stripped for numeric aggregations, but verify no custom path bypasses it
Defensive patterns

Strategy: try-catch

Type guard

function isSumAggError(err: unknown): boolean {
  return err instanceof Error && err.message.includes('sum aggregation');
}

Try / catch

try {
  await cluster.dbSize();
} catch (err) {
  if (err instanceof Error && err.message.includes('sum aggregation')) {
    // a shard returned non-number — check node health and version
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: DBSIZE or DEL under cluster mode where one shard returns a non-number reply; a multi_shard command where a sub-reply is not a number (e.g. one shard errors and the error reply resolves to a non-number); RESP decode interference.

Common situations: Mixed Redis versions where the command reply format differs; shard in a degraded state; type-mapping that converts numbers to strings in a way that bypasses the numeric-agg stripping.

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/d02d5a54745e40f2. Report an issue: GitHub.

Appendix: source

Thrown at packages/client/lib/cluster/request-response-policies/generic-aggregators.ts:155

    return aggregateElementwise(replies, Math.max, 'max') as T;
  }
  if (!replies.every((reply): reply is number => typeof reply === 'number')) {
    throw new Error('All replies must be numbers for max aggregation');
  }
  return Math.max(...replies) as T;
};

/**
 * Aggregates multiple numbers by finding the sum of all values.
 * @remarks
 * This implementation is specifically designed for Array<number> type only,
 * despite the generic type parameter. The generic type parameter T is provided
 * for usage ergonomy, but the actual input structure will be validated at runtime.
 */
export const aggregateSum = <T>(replies: Array<unknown>): T => {
  if (replies.length === 0) return 0 as T;
  if (!replies.every((reply): reply is number => typeof reply === 'number')) {
    throw new Error('All replies must be numbers for sum aggregation');
  }
  return replies.reduce((acc, reply) => acc + reply, 0) as T;
};


export const aggregateMerge = <T>(replies: Array<unknown>): T => {
	if(replies.length === 0) return undefined as T;

	const firstReply = replies[0]

	if(Array.isArray(firstReply)) {
		const set = new Set()
		for(const reply of replies) {
			for(const item of reply as Array<unknown>) {
				set.add(item);
			}
		}
		return Array.from(set) as T;

View on GitHub (pinned to 90fd0652bc)