redis/node-redis · error · Error

All replies must be array of numbers for logical AND…

Error message

All replies must be array of numbers for logical AND aggregation

What it means

Thrown by the agg_logical_and response reducer when at least one shard's reply is not an array of numbers. This policy is used by SCRIPT EXISTS (all_shards request policy), where each shard returns an array of 0/1 indicating script presence. The numeric aggregation pipeline strips type mappings before execution, so a NUMBER:String mapping should not trigger this — the error indicates a shard returned an unexpected reply shape.

Solutions

  1. Ensure all cluster nodes run the same Redis version
  2. Check cluster node health — a degraded node may return unexpected replies
  3. Verify no middleware or proxy is altering RESP replies
  4. If using a custom typeMapping, verify it does not affect the NUMBER type in a way that bypasses the numeric-agg stripping
Defensive patterns

Strategy: try-catch

Type guard

function isLogicalAndAggError(err: unknown): boolean {
  return err instanceof Error && err.message.includes('logical AND aggregation');
}

Try / catch

try {
  await cluster.scriptExists('sha1', 'sha2');
} catch (err) {
  if (err instanceof Error && err.message.includes('logical AND aggregation')) {
    // likely a shard-level issue — check node health, then retry or fall back
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: SCRIPT EXISTS under cluster mode where one shard returns a non-array reply (e.g. an error that somehow resolved, or a RESP decode that produced a different type); heterogeneous Redis versions where SCRIPT EXISTS returns a different reply shape; one shard in a degraded state returning a malformed RESP reply.

Common situations: Mixed Redis server versions across cluster shards; shard returning an unexpected error reply that gets coerced to a non-array; RESP2/RESP3 protocol mismatch between shards.

Related errors


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

Appendix: source

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

/**
 * Aggregates multiple arrays of numbers using logical AND operation.
 * @remarks
 * This implementation is specifically designed for Array<Array<number>> type only,
 * despite the generic type parameter. It is currently used by the SCRIPT EXISTS command
 * which returns an array of 0s and 1s from each shard.
 * The generic type parameter T is provided for usage ergonomy, but the actual input structure
 * will be validated at runtime.
 */
export const aggregateLogicalAnd = <T>(replies: Array<unknown>): T => {
  if (replies.length === 0) return [] as T;
  if (
    !replies.every(
      (reply): reply is number[] =>
        Array.isArray(reply) &&
        reply.every((value): value is number => typeof value === 'number')
    )
  ) {
    throw new Error(
      'All replies must be array of numbers for logical AND aggregation'
    );
  }

  const result = Array(replies[0].length).fill(1);

  for (const reply of replies) {
    for (let i = 0; i < reply.length; i++) {
      // clamp to 0/1: `&&` returns the operand, so non-binary replies would
      // otherwise leak through (e.g. 1 && 2 === 2).
      result[i] = result[i] && reply[i] ? 1 : 0;
    }
  }

  return result as T;
};

/**

View on GitHub (pinned to 90fd0652bc)