chroma-core/chroma · error · ValueError
Unknown rank operator: {op}
Error message
Unknown rank operator: {op} What it means
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.
Source
Thrown at chromadb/execution/expression/operator.py:870
elif op == "$min":
ranks_data = data["$min"]
if not isinstance(ranks_data, (list, tuple)):
raise TypeError(
f"$min requires a list, got {type(ranks_data).__name__}"
)
if len(ranks_data) < 2:
raise ValueError(
f"$min requires at least 2 ranks, got {len(ranks_data)}"
)
ranks = [Rank.from_dict(r) for r in ranks_data]
result = ranks[0]
for r in ranks[1:]:
result = result.min(r)
return result
else:
raise ValueError(f"Unknown rank operator: {op}")
# Arithmetic operators
def __add__(self, other: Union["Rank", float, int]) -> "Sum":
"""Addition: rank1 + rank2 or rank + value"""
other_rank = Val(other) if isinstance(other, (int, float)) else other
# Flatten if already Sum
if isinstance(self, Sum):
if isinstance(other_rank, Sum):
return Sum(self.ranks + other_rank.ranks)
return Sum(self.ranks + [other_rank])
elif isinstance(other_rank, Sum):
return Sum([self] + other_rank.ranks)
return Sum([self, other_rank])
def __radd__(self, other: Union[float, int]) -> "Sum":
"""Right addition: value + rank"""
return Val(other) + self
View on GitHub (pinned to aecdd12c8a)
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
Example fix
# before
expr = {"$multiply": [knn_rank, {"$val": 0.8}]}
# after
expr = {"$mul": [knn_rank, {"$val": 0.8}]} Defensive patterns
Strategy: type-guard
Validate before calling
RANK_OPS = {"$val", "$knn", "$sum", "$sub", "$mul", "$div",
"$abs", "$exp", "$log", "$max", "$min"}
op = next(iter(rank_expr)) if isinstance(rank_expr, dict) and rank_expr else None
if op not in RANK_OPS:
raise ValueError(f"unsupported rank operator {op!r}; supported: {sorted(RANK_OPS)}") Type guard
RANK_OPS = {"$val", "$knn", "$sum", "$sub", "$mul", "$div",
"$abs", "$exp", "$log", "$max", "$min"}
def is_rank_node(d) -> bool:
return (isinstance(d, dict) and len(d) == 1
and next(iter(d)) in RANK_OPS) Try / catch
try:
rank = Rank.from_dict(rank_expr)
except ValueError as e:
if "Unknown rank operator" in str(e):
raise ValueError(
f"unsupported operator in {rank_expr!r}; "
f"supported: $val,$knn,$sum,$sub,$mul,$div,$abs,$exp,$log,$max,$min"
) from e
raise Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- $sum requires at least 2 ranks, got {len(ranks_data)}
- $sub requires a dict with 'left' and 'right', got {type(sub_
- $sub requires 'left' and 'right' fields
- $mul requires a list, got {type(ranks_data).__name__}
- $mul requires at least 2 ranks, got {len(ranks_data)}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/f16d752c10ee9014.
Report an issue: GitHub.