redis/node-redis · error · Error

All replies must be number arrays of equal length for ${labe

Error message

All replies must be number arrays of equal length for ${label} aggregation

What it means

The element-wise helper used by `agg_min`/`agg_max` (array path, e.g. WAITAOF's [numlocal, numreplicas]) requires every shard reply to be a number array of the SAME length as the first reply before folding column-wise. Differing lengths or non-number elements abort the fold — element-wise min/max is undefined when columns don't line up.

Source

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

 * Shared by the array path of `aggregateMin`/`aggregateMax` so element-wise
 * aggregation matches the server's AGG_MIN/AGG_MAX semantics for commands
 * whose reply is an array (e.g. WAITAOF's `[numlocal, numreplicas]`).
 */
const aggregateElementwise = (
  replies: Array<unknown>,
  reduce: (a: number, b: number) => number,
  label: string
): Array<number> => {
  const length = (replies[0] as Array<unknown>).length;
  if (
    !replies.every(
      (reply): reply is number[] =>
        Array.isArray(reply) &&
        reply.length === length &&
        reply.every((value): value is number => typeof value === 'number')
    )
  ) {
    throw new Error(
      `All replies must be number arrays of equal length for ${label} aggregation`
    );
  }

  const result = (replies[0] as number[]).slice();
  for (let r = 1; r < replies.length; r++) {
    const reply = replies[r] as number[];
    for (let i = 0; i < length; i++) {
      result[i] = reduce(result[i], reply[i]);
    }
  }
  return result;
};

/**
 * Aggregates shard replies by taking the minimum value.
 * @remarks
 * Scalar replies (e.g. WAIT, the minimal number of synchronized replicas) fold

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Ensure all nodes run a Redis version with a consistent reply shape for the aggregated command.
  2. Run the command against each master directly to compare array lengths.
  3. Check for custom typeMapping or response-policy overrides that alter the reply shape.
Defensive patterns

Strategy: try-catch

Type guard

function isUniformNumberArrays(replies: unknown[]): replies is number[][] {
  return replies.every(r =>
    Array.isArray(r) && r.every(v => typeof v === 'number') && r.length === (replies[0] as number[])?.length
  );
}

Try / catch

try {
  await cluster.sendCommand(['WAITAOF', '1', '1', '0']);
} catch (e) {
  if (/number arrays of equal length/.test(e.message)) {
    // shard reply shapes diverge — check version parity
  } else throw e;
}

Prevention

When it happens

Trigger: A command tagged `agg_min`/`agg_max` whose first shard reply is an array, but some other shard returns an array of different length or with non-number elements. WAITAOF is the canonical example; any future command returning per-shard numeric arrays hits this if shapes diverge.

Common situations: Version skew where WAITAOF returns a 2-element array on some nodes and a different shape on others; a node error transformed into a non-array; mixed RESP versions producing different array shapes.

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/a7c90e286e415e7c.json. Report an issue: GitHub.