chroma-core/chroma · error · ValueError
Sum of weights must be positive when normalize=True
Error message
Sum of weights must be positive when normalize=True
What it means
With normalize=True, Chroma's Rrf rescales weights to sum to 1.0 by dividing each by sum(weights); a zero total would divide by zero, so Rrf.to_dict() raises this ValueError when all supplied weights are 0.0. Note the weights defaulting step treats only an empty/None list as 'unset' — an explicit all-zero list survives the non-negative check and fails here.
Source
Thrown at chromadb/execution/expression/operator.py:1224
raise ValueError(f"k must be positive, got {self.k}")
# Validate weights if provided
if self.weights is not None:
if len(self.weights) != len(self.ranks):
raise ValueError(
f"Number of weights ({len(self.weights)}) must match number of ranks ({len(self.ranks)})"
)
if any(w < 0.0 for w in self.weights):
raise ValueError("All weights must be non-negative")
# Populate weights with 1.0 if not provided
weights = self.weights if self.weights else [1.0] * len(self.ranks)
# Normalize weights if requested
if self.normalize:
weight_sum = sum(weights)
if weight_sum == 0:
raise ValueError("Sum of weights must be positive when normalize=True")
weights = [w / weight_sum for w in weights]
# Zip weights with ranks and build terms: weight / (k + rank)
terms = [w / (self.k + rank) for w, rank in zip(weights, self.ranks)]
# Sum all terms - guaranteed to have at least one
rrf_sum: Rank = terms[0]
for term in terms[1:]:
rrf_sum = rrf_sum + term
# Negate (RRF gives higher scores for better, Chroma needs lower for better)
return (-rrf_sum).to_dict()
@dataclass
class Select:
"""Selection configuration for search results.
View on GitHub (pinned to aecdd12c8a)
Solutions
- Give at least one strategy a strictly positive weight, e.g. weights=[0.0, 1.0]
- Drop normalize=True if you intentionally use relative (unnormalized) weights
- Validate before serializing: if normalize and sum(weights) <= 0: raise your own config error
- Guard computed weights: if total == 0, fall back to equal weights [1.0]*len(ranks) or skip the query
Example fix
# before rrf = Rrf(ranks=ranks, weights=[0.0, 0.0], normalize=True) # after rrf = Rrf(ranks=ranks, weights=[0.0, 1.0], normalize=True) # -> [0.0, 1.0]
Defensive patterns
Strategy: validation
Validate before calling
if normalize and sum(weights) <= 0:
raise ValueError(f"weights sum to {sum(weights)}; need > 0 when normalize=True")
rrf = Rrf(ranks=ranks, weights=weights, normalize=True, k=60) Type guard
def normalizable_weights(weights) -> bool:
return sum(weights) > 0 Try / catch
try:
plan = rrf.to_dict()
except ValueError as e:
raise ValueError(
f"invalid RRF weights {rrf.weights} for normalize={rrf.normalize}: {e}"
) from e Prevention
- Keep at least one strictly positive weight when normalize=True
- If strategies are disabled via zero weights, either drop normalize=True or rebuild the weights list without them
- Guard computed weight vectors with an all-zero check and fall back to equal weights
When it happens
Trigger: Rrf(ranks=[...], weights=[0.0, 0.0], normalize=True) then .to_dict() or query execution; also a longer weights vector that is entirely zeros, or weights computed by a formula (e.g. softmax at temperature ~0, or scores rounded down) that yields all zeros.
Common situations: Strategies disabled by setting their weight to 0 while normalize=True is kept on; weight vectors derived from external relevance data that can be all-zero for some tenants/queries; tuning loops that sweep weights including the all-zero corner.
Related errors
- All weights must be non-negative
- RRF requires at least one rank
- k must be positive, got {self.k}
- Number of weights ({len(self.weights)}) must match number of
- $sum requires at least 2 ranks, got {len(ranks_data)}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/dac658e30f39e0b4.
Report an issue: GitHub.