{"record":{"id":"f16d752c10ee9014","repo":"chroma-core/chroma","slug":"unknown-rank-operator-op","errorCode":null,"errorMessage":"Unknown rank operator: {op}","messagePattern":"Unknown rank operator: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/execution/expression/operator.py","lineNumber":870,"sourceCode":"        elif op == \"$min\":\n            ranks_data = data[\"$min\"]\n            if not isinstance(ranks_data, (list, tuple)):\n                raise TypeError(\n                    f\"$min requires a list, got {type(ranks_data).__name__}\"\n                )\n            if len(ranks_data) < 2:\n                raise ValueError(\n                    f\"$min requires at least 2 ranks, got {len(ranks_data)}\"\n                )\n\n            ranks = [Rank.from_dict(r) for r in ranks_data]\n            result = ranks[0]\n            for r in ranks[1:]:\n                result = result.min(r)\n            return result\n\n        else:\n            raise ValueError(f\"Unknown rank operator: {op}\")\n\n    # Arithmetic operators\n    def __add__(self, other: Union[\"Rank\", float, int]) -> \"Sum\":\n        \"\"\"Addition: rank1 + rank2 or rank + value\"\"\"\n        other_rank = Val(other) if isinstance(other, (int, float)) else other\n        # Flatten if already Sum\n        if isinstance(self, Sum):\n            if isinstance(other_rank, Sum):\n                return Sum(self.ranks + other_rank.ranks)\n            return Sum(self.ranks + [other_rank])\n        elif isinstance(other_rank, Sum):\n            return Sum([self] + other_rank.ranks)\n        return Sum([self, other_rank])\n\n    def __radd__(self, other: Union[float, int]) -> \"Sum\":\n        \"\"\"Right addition: value + rank\"\"\"\n        return Val(other) + self\n","sourceCodeStart":852,"sourceCodeEnd":888,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/execution/expression/operator.py#L852-L888","documentation":"Rank.from_dict dispatches on the single operator key of a rank-expression dict and supports exactly $val, $knn, $sum, $sub, $mul, $div, $abs, $exp, $log, $max, $min. Any other key — a typo, wrong casing, or an operator introduced in a newer Chroma version — reaches the final else branch and raises this ValueError.","triggerScenarios":"Rank.from_dict({'$multiply': [...]}) (wrong name), {'$Sum': [...]} (wrong case), {'$avg': [...]} (unsupported operator), or an expression emitted by a newer client using an operator this version does not know, deserialized by an older server (or vice versa).","commonSituations":"Hand-written JSON with guessed operator names (MongoDB-style $multiply/$add habits); version skew between Chroma client and server where one side supports a newer rank DSL; copy-paste from docs of a different version; experimental operators removed or renamed between versions.","solutions":["Correct the operator name and casing to one of: $val, $knn, $sum, $sub, $mul, $div, $abs, $exp, $log, $max, $min","Check the supported-operator list in your installed version's Rank.from_dict docstring (chromadb/execution/expression/operator.py) if unsure","Align client and server versions (pip install -U chromadb on both) when the expression comes from another component","Validate the operator key against the known set before deserialization"],"exampleFix":"# before\nexpr = {\"$multiply\": [knn_rank, {\"$val\": 0.8}]}\n\n# after\nexpr = {\"$mul\": [knn_rank, {\"$val\": 0.8}]}","handlingStrategy":"type-guard","validationCode":"RANK_OPS = {\"$val\", \"$knn\", \"$sum\", \"$sub\", \"$mul\", \"$div\",\n            \"$abs\", \"$exp\", \"$log\", \"$max\", \"$min\"}\n\nop = next(iter(rank_expr)) if isinstance(rank_expr, dict) and rank_expr else None\nif op not in RANK_OPS:\n    raise ValueError(f\"unsupported rank operator {op!r}; supported: {sorted(RANK_OPS)}\")","typeGuard":"RANK_OPS = {\"$val\", \"$knn\", \"$sum\", \"$sub\", \"$mul\", \"$div\",\n            \"$abs\", \"$exp\", \"$log\", \"$max\", \"$min\"}\n\ndef is_rank_node(d) -> bool:\n    return (isinstance(d, dict) and len(d) == 1\n            and next(iter(d)) in RANK_OPS)","tryCatchPattern":"try:\n    rank = Rank.from_dict(rank_expr)\nexcept ValueError as e:\n    if \"Unknown rank operator\" in str(e):\n        raise ValueError(\n            f\"unsupported operator in {rank_expr!r}; \"\n            f\"supported: $val,$knn,$sum,$sub,$mul,$div,$abs,$exp,$log,$max,$min\"\n        ) from e\n    raise","preventionTips":["Pin client and server to the same chromadb version when expressions cross a process boundary","Reject unknown operator keys at your API boundary with the supported list in the message","Copy operator names from Rank.from_dict's docstring, not from memory or MongoDB conventions"],"tags":["chromadb","rank-expression","validation","unknown-operator","version-skew"],"backgroundTag":"query-expression-validation","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}