{"record":{"id":"6341fa1afac28a97","repo":"chroma-core/chroma","slug":"rank-dict-must-contain-exactly-one-operator-got","errorCode":null,"errorMessage":"Rank dict must contain exactly one operator, got {len(data)}","messagePattern":"Rank dict must contain exactly one operator, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/execution/expression/operator.py","lineNumber":677,"sourceCode":"        - {\"$knn\": {...}} -> Knn(...)\n        - {\"$sum\": [ranks]} -> rank1 + rank2 + ...\n        - {\"$sub\": {\"left\": ..., \"right\": ...}} -> left - right\n        - {\"$mul\": [ranks]} -> rank1 * rank2 * ...\n        - {\"$div\": {\"left\": ..., \"right\": ...}} -> left / right\n        - {\"$abs\": rank} -> abs(rank)\n        - {\"$exp\": rank} -> rank.exp()\n        - {\"$log\": rank} -> rank.log()\n        - {\"$max\": [ranks]} -> rank1.max(rank2).max(rank3)...\n        - {\"$min\": [ranks]} -> rank1.min(rank2).min(rank3)...\n        \"\"\"\n        if not isinstance(data, dict):\n            raise TypeError(f\"Expected dict for Rank, got {type(data).__name__}\")\n\n        if not data:\n            raise ValueError(\"Rank dict cannot be empty\")\n\n        if len(data) != 1:\n            raise ValueError(\n                f\"Rank dict must contain exactly one operator, got {len(data)}\"\n            )\n\n        op = next(iter(data.keys()))\n\n        if op == \"$val\":\n            value = data[\"$val\"]\n            if not isinstance(value, (int, float)):\n                raise TypeError(f\"$val requires a number, got {type(value).__name__}\")\n            return Val(value)\n\n        elif op == \"$knn\":\n            knn_data = data[\"$knn\"]\n            if not isinstance(knn_data, dict):\n                raise TypeError(f\"$knn requires a dict, got {type(knn_data).__name__}\")\n\n            if \"query\" not in knn_data:\n                raise ValueError(\"$knn requires 'query' field\")","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/execution/expression/operator.py#L659-L695","documentation":"A rank dict must contain exactly one operator key ($val, $knn, $sum, ...). Two or more keys in the same dict raise ValueError because the grammar has no sibling-key composition: combining expressions is expressed by nesting them under arithmetic operators, never by merging keys into one dict.","triggerScenarios":"Search(rank={'$val': 0.5, '$knn': {'query': [...]}}); dict-merging two expressions ({**a, **b}); nested case {'$sum': [{'$val': 1, '$abs': {'$val': -1}}]} where the inner dict has 2 keys.","commonSituations":"Trying to 'add a boost' by merging a constant into an existing Knn dict; config systems that deep-merge rank blocks; assuming sibling keys behave like $and when building weighted scores.","solutions":["Express combinations with arithmetic operators: {'$sum': [{'$val': 0.5}, {'$knn': {...}}]}.","Use the class API: Val(0.5) + Knn(query=[...]).","Never dict-merge (** or |=) rank expressions."],"exampleFix":"# before\nSearch(rank={'$val': 0.5, '$knn': {'query': emb}})   # 2 keys -> ValueError\n\n# after\nSearch(rank={'$sum': [{'$val': 0.5}, {'$knn': {'query': emb}}]})","handlingStrategy":"validation","validationCode":"def valid_rank_shape(node) -> bool:\n    return isinstance(node, dict) and len(node) == 1\n\nif rank_cfg is not None and not valid_rank_shape(rank_cfg):\n    raise ValueError(f'rank must have exactly one operator, got {list(rank_cfg)}')\nSearch(rank=rank_cfg)","typeGuard":"def is_single_operator_dict(node) -> bool:\n    return isinstance(node, dict) and len(node) == 1 and next(iter(node), '').startswith('$')","tryCatchPattern":null,"preventionTips":["One operator per dict - combine via $sum/$mul/$max or the class API's overloaded operators.","Never **-merge rank dicts.","Validate user-built rank trees for the single-key rule before calling Search()."],"tags":["validation","valueerror","rank","expression","chromadb"],"backgroundTag":"schema-validation-failed","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}