{"record":{"id":"efa6f19f57b39a39","repo":"chroma-core/chroma","slug":"all-weights-must-be-non-negative","errorCode":null,"errorMessage":"All weights must be non-negative","messagePattern":"All weights must be non-negative","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/execution/expression/operator.py","lineNumber":1215,"sourceCode":"        \"\"\"Convert RRF to a composition of existing expression operators.\n\n        Builds: -sum(weight_i / (k + rank_i)) for each rank\n        Using Python's overloaded operators for cleaner code.\n        \"\"\"\n        # Validate RRF parameters\n        if not self.ranks:\n            raise ValueError(\"RRF requires at least one rank\")\n        if self.k <= 0:\n            raise ValueError(f\"k must be positive, got {self.k}\")\n\n        # Validate weights if provided\n        if self.weights is not None:\n            if len(self.weights) != len(self.ranks):\n                raise ValueError(\n                    f\"Number of weights ({len(self.weights)}) must match number of ranks ({len(self.ranks)})\"\n                )\n            if any(w < 0.0 for w in self.weights):\n                raise ValueError(\"All weights must be non-negative\")\n\n        # Populate weights with 1.0 if not provided\n        weights = self.weights if self.weights else [1.0] * len(self.ranks)\n\n        # Normalize weights if requested\n        if self.normalize:\n            weight_sum = sum(weights)\n            if weight_sum == 0:\n                raise ValueError(\"Sum of weights must be positive when normalize=True\")\n            weights = [w / weight_sum for w in weights]\n\n        # Zip weights with ranks and build terms: weight / (k + rank)\n        terms = [w / (self.k + rank) for w, rank in zip(weights, self.ranks)]\n\n        # Sum all terms - guaranteed to have at least one\n        rrf_sum: Rank = terms[0]\n        for term in terms[1:]:\n            rrf_sum = rrf_sum + term","sourceCodeStart":1197,"sourceCodeEnd":1233,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/execution/expression/operator.py#L1197-L1233","documentation":"Weights in Chroma's Rrf scale each strategy's contribution weight_i / (k + rank_i), and negative weights would invert a strategy's ranking order rather than weight it — so Rrf.to_dict() rejects any weight < 0 with this ValueError at serialization/query time. Zero weights are allowed (they disable a strategy) unless normalize=True makes the total zero.","triggerScenarios":"Rrf(ranks=[...], weights=[-1.0, 2.0], ...) then .to_dict() or query execution; commonly a sign error in tuning code, or weights computed as a difference that can go negative.","commonSituations":"See trigger scenarios.","solutions":["Use non-negative weights; to demote a strategy, lower its weight toward 0.0 instead of negating it","If weights are computed, clamp: weights = [max(0.0, w) for w in weights]","Validate all(w >= 0 for w in weights) before constructing/serializing Rrf and fail with your own message","Re-check the intent: inverting a ranking is not achievable via negative RRF weight; use a different rank expression if that is the goal"],"exampleFix":"# before\nrrf = Rrf(ranks=ranks, weights=[-0.5, 2.0], k=60)\n\n# after\nrrf = Rrf(ranks=ranks, weights=[0.5, 2.0], k=60)","handlingStrategy":"validation","validationCode":"if any(w < 0 for w in weights):\n    raise ValueError(f\"RRF weights must be non-negative: {weights}\")\nrrf = Rrf(ranks=ranks, weights=weights, k=60)","typeGuard":"def non_negative_weights(weights) -> bool:\n    return all(isinstance(w, (int, float)) and w >= 0 for w in weights)","tryCatchPattern":"try:\n    plan = rrf.to_dict()\nexcept ValueError as e:\n    raise ValueError(f\"invalid RRF weights {rrf.weights}: {e}\") from e","preventionTips":["Use 0.0 to disable a strategy, never a negative weight","Clamp computed weights: max(0.0, w) before passing them in","Remember negative RRF weights cannot invert a ranking; redesign the expression instead"],"tags":["chromadb","rrf","rank-expression","validation","weights"],"backgroundTag":"rrf-invalid-parameters","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}