{"record":{"id":"b0a94b481e8cd42f","repo":"chroma-core/chroma","slug":"k-must-be-positive-got-self-k","errorCode":null,"errorMessage":"k must be positive, got {self.k}","messagePattern":"k must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/execution/expression/operator.py","lineNumber":1206,"sourceCode":"        )\n    \"\"\"\n\n    ranks: List[Rank]\n    k: int = 60\n    weights: Optional[List[float]] = None\n    normalize: bool = False\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"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\")","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/execution/expression/operator.py#L1188-L1224","documentation":"The k parameter of Chroma's Rrf is the reciprocal-rank smoothing constant (default 60, the standard literature value) that appears as weight_i / (k + rank_i). Rrf.to_dict() validates k > 0 and raises this ValueError at serialization/query time when k is zero or negative, because those values make the fusion terms degenerate or sign-flipped.","triggerScenarios":"Rrf(ranks=[...], k=0) or k=-5, then .to_dict() or executing the query that contains it. Commonly k is read from config or a CLI flag that defaults to 0/'not set' and is passed through unchecked.","commonSituations":"Config plumbing where an unset value becomes 0 (e.g. int(os.environ.get('RRF_K', 0))); tuning scripts sweeping k including 0; a 'disable smoothing' intent incorrectly encoded as k=0.","solutions":["Use a positive k — the standard default is 60; omit the parameter to get 60","Validate config before constructing: k = k if k and k > 0 else 60","If k comes from user input, clamp or reject with your own clear error before the query","Wrap serialization in try/except ValueError to surface which RRF parameter was invalid"],"exampleFix":"# before\nrrf = Rrf(ranks=ranks, k=int(cfg.get(\"rrf_k\", 0)))  # 0 when unset\n\n# after\nk = int(cfg.get(\"rrf_k\", 60))\nif k <= 0:\n    raise ValueError(f\"rrf_k must be positive, got {k}\")\nrrf = Rrf(ranks=ranks, k=k)","handlingStrategy":"validation","validationCode":"k = int(cfg.get(\"rrf_k\", 60))\nif k <= 0:\n    raise ValueError(f\"rrf_k must be positive, got {k}\")\nrrf = Rrf(ranks=ranks, k=k)","typeGuard":"def is_positive_k(k) -> bool:\n    return isinstance(k, int) and k > 0","tryCatchPattern":"try:\n    plan = rrf.to_dict()\nexcept ValueError as e:\n    raise ValueError(f\"invalid RRF configuration (k={rrf.k}): {e}\") from e","preventionTips":["Default k to 60 and never pass config zeros straight through","Validate externally supplied k (env vars, CLI flags, request params) as a positive int before building Rrf","Remember the error surfaces at serialization, so validate early for a clear stack trace"],"tags":["chromadb","rrf","rank-expression","validation","configuration"],"backgroundTag":"rrf-invalid-parameters","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}