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

  1. Give at least one strategy a strictly positive weight, e.g. weights=[0.0, 1.0]
  2. Drop normalize=True if you intentionally use relative (unnormalized) weights
  3. Validate before serializing: if normalize and sum(weights) <= 0: raise your own config error
  4. 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

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


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