{"record":{"id":"ba709ebe8265a39d","repo":"redis/node-redis","slug":"all-replies-must-be-array-of-numbers-for-logical-o","errorCode":null,"errorMessage":"All replies must be array of numbers for logical OR aggregation","messagePattern":"All replies must be array of numbers for logical OR aggregation","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/lib/cluster/request-response-policies/generic-aggregators.ts","lineNumber":54,"sourceCode":"\n/**\n * Aggregates multiple arrays of numbers using logical OR operation.\n * @remarks\n * Mirror of `aggregateLogicalAnd` for the `agg_logical_or` response policy.\n * No command in the current metadata snapshot uses it, but the reducer is\n * registered in `RESPONSE_REDUCERS`, so it must be correct for the first\n * command a future metadata regeneration tags with it.\n */\nexport const aggregateLogicalOr = <T>(replies: Array<unknown>): T => {\n  if (replies.length === 0) return [] as T;\n  if (\n    !replies.every(\n      (reply): reply is number[] =>\n        Array.isArray(reply) &&\n        reply.every((value): value is number => typeof value === 'number')\n    )\n  ) {\n    throw new Error(\n      'All replies must be array of numbers for logical OR aggregation'\n    );\n  }\n\n  const result = Array(replies[0].length).fill(0);\n\n  for (const reply of replies) {\n    for (let i = 0; i < reply.length; i++) {\n      // clamp to 0/1: `||` returns the operand, so non-binary replies would\n      // otherwise leak through (e.g. 0 || 3 === 3).\n      result[i] = result[i] || reply[i] ? 1 : 0;\n    }\n  }\n\n  return result as T;\n};\n\n/**","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/cluster/request-response-policies/generic-aggregators.ts#L36-L72","documentation":"Thrown by the agg_logical_or response reducer when at least one shard's reply is not an array of numbers. This is the OR counterpart to the logical AND reducer. No command in the current static metadata snapshot uses agg_logical_or, so encountering this error means a future metadata regeneration or a dynamic COMMAND DOCS response tagged a command with this policy whose reply shape is incompatible.","triggerScenarios":"A command dynamically discovered via COMMAND DOCS tagged with agg_logical_or whose shard replies are not arrays of numbers; a metadata regeneration that adds this policy to a command with an unexpected reply shape.","commonSituations":"New Redis version introduces a command tagged agg_logical_or; custom metadata override that assigns this policy incorrectly.","solutions":["Identify which command triggered the error and verify its reply shape matches what agg_logical_or expects (array of numbers per shard)","If the command's reply shape is incompatible, report it as a metadata mismatch","Fall back to issuing the command to a single node via sendCommand if cluster-wide aggregation is not needed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isLogicalOrAggError(err: unknown): boolean {\n  return err instanceof Error && err.message.includes('logical OR aggregation');\n}","tryCatchPattern":"try {\n  // the command that triggered agg_logical_or\n  await cluster.sendCommand(RO, 'COMMAND_NAME', ['arg']);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('logical OR aggregation')) {\n    // no standard command currently uses this — report as metadata issue\n  } else {\n    throw err;\n  }\n}","preventionTips":["No standard command currently uses agg_logical_or — encountering this indicates a metadata issue","If a future metadata regeneration introduces this policy, verify the command's reply shape","Report the command name and arguments if this error fires"],"tags":["cluster","aggregation","metadata","response-validation"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}