chroma-core/chroma · error · Error

Sum requires at least one rank expression

Error message

Sum requires at least one rank expression

What it means

Thrown by the Sum rank factory (rank.ts:505) when called with zero arguments. Sum is variadic — Sum(a, b, ...) — and needs at least one operand to build the {$sum: [...]} JSON. Note the asymmetry: the method form expr.add() with no arguments returns expr unchanged, but the top-level Sum() factory with no arguments throws.

Source

Thrown at clients/new-js/packages/chromadb/src/execution/expression/rank.ts:505

      );
    }
    weightValues = weightValues.map((value) => value / total);
  }

  const terms = expressions.map((rank, index) => {
    const weight = weightValues[index];
    const numerator = Val(weight);
    const denominator = rank.add(k);
    return numerator.divide(denominator);
  });

  const fused = terms.reduce((acc, term) => acc.add(term));
  return fused.negate();
};

export const Sum = (...inputs: RankInput[]): RankExpression => {
  if (inputs.length === 0) {
    throw new Error("Sum requires at least one rank expression");
  }
  const expressions = inputs.map((rank, index) =>
    requireRank(rank, `Sum operand ${index}`),
  );
  return SumRankExpression.create(expressions);
};

export const Sub = (left: RankInput, right: RankInput): RankExpression =>
  new SubRankExpression(
    requireRank(left, "Sub left"),
    requireRank(right, "Sub right"),
  );

export const Mul = (...inputs: RankInput[]): RankExpression => {
  if (inputs.length === 0) {
    throw new Error("Mul requires at least one rank expression");
  }
  const expressions = inputs.map((rank, index) =>

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Ensure at least one operand: Sum(a, b) or Sum(...parts) with parts.length >= 1
  2. Use a neutral identity for the empty case: Sum(...(parts.length ? parts : [0]))
  3. Skip building the expression entirely when there is nothing to sum

Example fix

// before
const rank = Sum(...components); // throws when components is []

// after
const rank = Sum(...(components.length ? components : [0]));
// or: const rank = components.length ? Sum(...components) : Val(0);
Defensive patterns

Strategy: validation

Validate before calling

const rank = components.length
  ? Sum(...components)
  : Val(0); // additive identity

Try / catch

try {
  const rank = Sum(...components);
} catch (e) {
  if (e instanceof Error && e.message.includes('Sum requires')) {
    return Val(0);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Sum() directly; spreading a possibly-empty array: Sum(...parts) where parts.length === 0. Common with dynamically collected scoring components where every component was filtered out or disabled.

Common situations: Aggregating conditionally-built score components behind feature flags; list-producing queries that return no components (empty result set, all filtered); refactors that moved a guaranteed operand into an optional variable.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/1e1e15c603732753. Report an issue: GitHub.