chroma-core/chroma · error · Error
Weights must sum to a positive value when normalize=true
Error message
Weights must sum to a positive value when normalize=true
What it means
Thrown by Rrf (rank.ts:485) when normalize=true and the weights sum to zero or less. Normalization divides each weight by the total, so a zero total would divide by zero; since negative weights are already rejected by the previous check, this fires in practice when all weights are exactly 0.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/rank.ts:485
const expressions = ranks.map((rank, index) =>
requireRank(rank, `ranks[${index}]`),
);
let weightValues = weights
? weights.slice()
: new Array(expressions.length).fill(1);
if (weightValues.length !== expressions.length) {
throw new Error("Number of weights must match number of ranks");
}
if (weightValues.some((value) => typeof value !== "number" || value < 0)) {
throw new TypeError("Weights must be non-negative numbers");
}
if (normalize) {
const total = weightValues.reduce((sum, value) => sum + value, 0);
if (total <= 0) {
throw new Error(
"Weights must sum to a positive value when normalize=true",
);
}
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 => {View on GitHub (pinned to aecdd12c8a)
Solutions
- Give at least one weight a positive value, or use defaults by omitting weights (all 1s)
- Treat all-zero as 'no preference': drop weights and pass normalize: false
- Guard before calling: if (normalize && weights.reduce((s, w) => s + w, 0) <= 0) use unweighted ranks
Example fix
// before
const fused = Rrf({ ranks, weights: mix, normalize: true }); // mix = [0, 0]
// after
const total = mix.reduce((s, w) => s + w, 0);
const fused =
total > 0
? Rrf({ ranks, weights: mix, normalize: true })
: Rrf({ ranks }); // uniform fallback Defensive patterns
Strategy: validation
Validate before calling
const total = weights.reduce((s, w) => s + w, 0);
const fused =
total > 0
? Rrf({ ranks, weights, normalize: true })
: Rrf({ ranks }); // all-zero mix: use uniform Try / catch
try {
const fused = Rrf({ ranks, weights, normalize: true });
} catch (e) {
if (e instanceof Error && e.message.includes('positive value')) {
return Rrf({ ranks, weights, normalize: false });
}
throw e;
} Prevention
- Treat an all-zero weight vector as 'no preference' and drop weights
- Keep a guaranteed positive baseline weight in tuning UIs
- Normalize totals in your own code before enabling normalize
When it happens
Trigger: Calling Rrf({ ranks: [a, b], weights: [0, 0], normalize: true }) — disabling every ranker while asking for normalized output; dynamic weight schedules (e.g. time-based decay) that hit all-zero; user sliders all set to 0 in a tuning UI.
Common situations: Retriever-mixing UIs where users can zero out every component; softmax/decay computations that underflow to 0; enabling normalize by default while weights come from a sparse config where unset means 0 rather than 1.
Related errors
- Number of weights must match number of ranks
- Weights must be non-negative numbers
- All weights must be non-negative
- Sum of weights must be positive when normalize=True
- Rrf k must be a positive integer
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/eaf993119951c716.
Report an issue: GitHub.