{"record":{"id":"7ef6bdb0d33a8981","repo":"chroma-core/chroma","slug":"max-requires-at-least-one-rank-expression","errorCode":null,"errorMessage":"Max requires at least one rank expression","messagePattern":"Max requires at least one rank expression","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/rank.ts","lineNumber":546,"sourceCode":"\nexport const Div = (left: RankInput, right: RankInput): RankExpression =>\n  new DivRankExpression(\n    requireRank(left, \"Div left\"),\n    requireRank(right, \"Div right\"),\n  );\n\nexport const Abs = (input: RankInput): RankExpression =>\n  requireRank(input, \"Abs\").abs();\n\nexport const Exp = (input: RankInput): RankExpression =>\n  requireRank(input, \"Exp\").exp();\n\nexport const Log = (input: RankInput): RankExpression =>\n  requireRank(input, \"Log\").log();\n\nexport const Max = (...inputs: RankInput[]): RankExpression => {\n  if (inputs.length === 0) {\n    throw new Error(\"Max requires at least one rank expression\");\n  }\n  const expressions = inputs.map((rank, index) =>\n    requireRank(rank, `Max operand ${index}`),\n  );\n  return MaxRankExpression.create(expressions);\n};\n\nexport const Min = (...inputs: RankInput[]): RankExpression => {\n  if (inputs.length === 0) {\n    throw new Error(\"Min requires at least one rank expression\");\n  }\n  const expressions = inputs.map((rank, index) =>\n    requireRank(rank, `Min operand ${index}`),\n  );\n  return MinRankExpression.create(expressions);\n};\n","sourceCodeStart":528,"sourceCodeEnd":563,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/rank.ts#L528-L563","documentation":"Thrown by the Max rank factory (rank.ts:546) when called with zero arguments. Max builds {$max: [...]} and requires at least one rank expression. The method form expr.max() with no arguments returns expr; only the bare factory Max() with no operands throws.","triggerScenarios":"Calling Max(); spreading a dynamic list Max(...candidates) where candidates is empty — e.g. a 'best of selected signals' expression where no signal was selected.","commonSituations":"Max-over-optional-scorers UIs (pick best of enabled signals); empty candidate sets from upstream filters; conditional assembly that forgot a guaranteed baseline operand.","solutions":["Pass at least one operand: Max(a, b)","Include a baseline for the empty case: Max(...(signals.length ? signals : [0]))","Skip building the expression when the list is empty"],"exampleFix":"// before\nconst rank = Max(...signals); // throws when signals is []\n\n// after\nconst rank = signals.length ? Max(...signals) : Val(0);","handlingStrategy":"validation","validationCode":"const rank = signals.length\n  ? Max(...signals)\n  : Val(0);","typeGuard":null,"tryCatchPattern":"try {\n  const rank = Max(...signals);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Max requires')) {\n    return Val(0);\n  }\n  throw e;\n}","preventionTips":["Always include a baseline signal in max-of-signals pipelines","Gate the expression on signals.length before spreading"],"tags":["max","rank-expression","empty-arguments","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}