{"record":{"id":"a7c90e286e415e7c","repo":"redis/node-redis","slug":"all-replies-must-be-number-arrays-of-equal-length","errorCode":null,"errorMessage":"All replies must be number arrays of equal length for ${label} aggregation","messagePattern":"All replies must be number arrays of equal length for (.+?) aggregation","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/lib/cluster/request-response-policies/generic-aggregators.ts","lineNumber":93,"sourceCode":" * Shared by the array path of `aggregateMin`/`aggregateMax` so element-wise\n * aggregation matches the server's AGG_MIN/AGG_MAX semantics for commands\n * whose reply is an array (e.g. WAITAOF's `[numlocal, numreplicas]`).\n */\nconst aggregateElementwise = (\n  replies: Array<unknown>,\n  reduce: (a: number, b: number) => number,\n  label: string\n): Array<number> => {\n  const length = (replies[0] as Array<unknown>).length;\n  if (\n    !replies.every(\n      (reply): reply is number[] =>\n        Array.isArray(reply) &&\n        reply.length === length &&\n        reply.every((value): value is number => typeof value === 'number')\n    )\n  ) {\n    throw new Error(\n      `All replies must be number arrays of equal length for ${label} aggregation`\n    );\n  }\n\n  const result = (replies[0] as number[]).slice();\n  for (let r = 1; r < replies.length; r++) {\n    const reply = replies[r] as number[];\n    for (let i = 0; i < length; i++) {\n      result[i] = reduce(result[i], reply[i]);\n    }\n  }\n  return result;\n};\n\n/**\n * Aggregates shard replies by taking the minimum value.\n * @remarks\n * Scalar replies (e.g. WAIT, the minimal number of synchronized replicas) fold","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/cluster/request-response-policies/generic-aggregators.ts#L75-L111","documentation":"Thrown by the element-wise min/max aggregator when shard replies are arrays of unequal lengths or contain non-number elements. Used for commands whose reply is a fixed-length number array folded element-wise (e.g. WAITAOF returns [numlocal, numreplicas]). Each shard must return an array of the same length so columns align.","triggerScenarios":"WAITAOF under all_shards where shards return arrays of different lengths — e.g. one shard returns [1,2] and another returns [1]; a shard returning an array containing non-number elements (strings, nulls) under an unusual type mapping or RESP variant.","commonSituations":"Heterogeneous cluster where nodes run different Redis versions and WAITAOF reply arity differs; one shard erroring and returning a partial or differently-shaped reply.","solutions":["Ensure all cluster nodes run the same Redis version (WAITAOF reply shape can vary by version)","Check for shard-level errors or degraded nodes returning unexpected replies","Avoid mixing RESP2 and RESP3 across cluster nodes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isElementwiseAggError(err: unknown): boolean {\n  return err instanceof Error && err.message.includes('number arrays of equal length');\n}","tryCatchPattern":"try {\n  await cluster.waitAOF(1, 1, 0);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('number arrays of equal length')) {\n    // shard reply shapes differ — check for version mismatch or degraded nodes\n  } else {\n    throw err;\n  }\n}","preventionTips":["Ensure all cluster nodes run the same Redis version (WAITAOF reply arity can vary)","Do not mix RESP2 and RESP3 across cluster nodes","Monitor shard health for degraded nodes returning unexpected reply shapes"],"tags":["cluster","aggregation","waitaof","response-validation"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}