chroma-core/chroma · error · ValueError
Rank dict cannot be empty
Error message
Rank dict cannot be empty
What it means
An empty dict is not a valid rank expression: Rank.from_dict({}) raises ValueError because there is no operator key to dispatch. Every rank node must carry exactly one $-prefixed operator, so {} almost always means an absent optional rank was forwarded anyway, or a nested operand is empty.
Source
Thrown at chromadb/execution/expression/operator.py:674
Supports operators:
- {"$val": number} -> Val(number)
- {"$knn": {...}} -> Knn(...)
- {"$sum": [ranks]} -> rank1 + rank2 + ...
- {"$sub": {"left": ..., "right": ...}} -> left - right
- {"$mul": [ranks]} -> rank1 * rank2 * ...
- {"$div": {"left": ..., "right": ...}} -> left / right
- {"$abs": rank} -> abs(rank)
- {"$exp": rank} -> rank.exp()
- {"$log": rank} -> rank.log()
- {"$max": [ranks]} -> rank1.max(rank2).max(rank3)...
- {"$min": [ranks]} -> rank1.min(rank2).min(rank3)...
"""
if not isinstance(data, dict):
raise TypeError(f"Expected dict for Rank, got {type(data).__name__}")
if not data:
raise ValueError("Rank dict cannot be empty")
if len(data) != 1:
raise ValueError(
f"Rank dict must contain exactly one operator, got {len(data)}"
)
op = next(iter(data.keys()))
if op == "$val":
value = data["$val"]
if not isinstance(value, (int, float)):
raise TypeError(f"$val requires a number, got {type(value).__name__}")
return Val(value)
elif op == "$knn":
knn_data = data["$knn"]
if not isinstance(knn_data, dict):
raise TypeError(f"$knn requires a dict, got {type(knn_data).__name__}")View on GitHub (pinned to aecdd12c8a)
Solutions
- Pass rank=None to disable ranking.
- Use rank_cfg or None instead of {} when the config may be missing.
- When building trees programmatically, never emit a node whose operands are absent.
Example fix
# before
rank_cfg = user_params.get('rank', {}) # missing -> {}
Search(rank=rank_cfg) # -> ValueError: cannot be empty
# after
rank_cfg = user_params.get('rank') or None # {} also becomes None
Search(rank=rank_cfg) Defensive patterns
Strategy: validation
Validate before calling
rank_cfg = request.get('rank') or None # {} becomes None
Search(rank=rank_cfg) Type guard
def is_valid_rank_dict(node) -> bool:
return isinstance(node, dict) and len(node) == 1 Prevention
- Normalize empty or missing optional expressions to None before building Search.
- Default expression config values to None, never {}.
- In code generators, skip emitting a node when its operands are absent.
When it happens
Trigger: Search(rank={}); Rank.from_dict({}); nested empties like {'$sum': [{}, {'$val': 1}]} where the empty child recurses into Rank.from_dict({}).
Common situations: Optional rank config defaulted with {} (user_cfg.get('rank', {})) and passed unconditionally; templating that renders an empty expression when a variable is missing; 'clearing' a rank by assigning {} instead of None.
Related errors
- Rank dict must contain exactly one operator, got {len(data)}
- Expected dict for Rank, got {type(data).__name__}
- $knn requires 'query' field
- $sum requires a list, got {type(ranks_data).__name__}
- Limit offset must be non-negative, got {offset}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/65c4a6448e3f00a4.
Report an issue: GitHub.