chroma-core/chroma · error · TypeError
$div requires a dict with 'left' and 'right', got {type(div_
Error message
$div requires a dict with 'left' and 'right', got {type(div_data).__name__} What it means
The $div rank operator models division of two rank expressions (e.g. normalizing a KNN score by a constant) and, like $sub, expects a dict with 'left' and 'right' keys rather than an operand list. Rank.from_dict raises this TypeError when the $div payload is not a dict — commonly a two-element list written in the $sum/$mul style.
Source
Thrown at chromadb/execution/expression/operator.py:801
if not isinstance(ranks_data, (list, tuple)):
raise TypeError(
f"$mul requires a list, got {type(ranks_data).__name__}"
)
if len(ranks_data) < 2:
raise ValueError(
f"$mul 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 * r
return result
elif op == "$div":
div_data = data["$div"]
if not isinstance(div_data, dict):
raise TypeError(
f"$div requires a dict with 'left' and 'right', got {type(div_data).__name__}"
)
if "left" not in div_data or "right" not in div_data:
raise ValueError("$div requires 'left' and 'right' fields")
left = Rank.from_dict(div_data["left"])
right = Rank.from_dict(div_data["right"])
return left / right
elif op == "$abs":
child_data = data["$abs"]
if not isinstance(child_data, dict):
raise TypeError(
f"$abs requires a rank dict, got {type(child_data).__name__}"
)
return abs(Rank.from_dict(child_data))
elif op == "$exp":View on GitHub (pinned to aecdd12c8a)
Solutions
- Encode division as {"$div": {"left": numerator, "right": denominator}}
- Convert list-shaped input before sending: {'$div': {'left': pair[0], 'right': pair[1]}}
- Build in Python as numerator / denominator (or rank / 10.0) and call .to_dict()
- Guard with isinstance(expr['$div'], dict) before Rank.from_dict
Example fix
# before
expr = {"$div": [knn_rank, {"$val": 10.0}]}
# after
expr = {"$div": {"left": knn_rank, "right": {"$val": 10.0}}} Defensive patterns
Strategy: validation
Validate before calling
def valid_div_expr(expr):
return (
isinstance(expr, dict) and set(expr) == {"$div"}
and isinstance(expr["$div"], dict)
)
if not valid_div_expr(rank_expr):
raise ValueError(f"$div payload must be a dict with left/right, got {rank_expr!r}") Type guard
def is_div_expr(d) -> bool:
return (isinstance(d, dict) and set(d) == {"$div"}
and isinstance(d["$div"], dict)) Try / catch
try:
rank = Rank.from_dict(rank_expr)
except (TypeError, ValueError) as e:
raise ValueError(f"invalid rank expression {rank_expr!r}: {e}") from e Prevention
- $div follows the $sub convention ({'left','right'}), not the list convention
- Build normalization in Python: (rank / 10.0).to_dict()
- Test serialization round-trips for every expression shape you emit
When it happens
Trigger: Rank.from_dict({'$div': [numerator, denominator]}) or {'$div': 10}, including nested occurrences inside a larger expression tree.
Common situations: Using the list payload convention for every arithmetic operator in generated JSON; hand-writing a normalization expression and guessing the shape; copying the $sum pattern when adding division.
Related errors
- $sub requires a dict with 'left' and 'right', got {type(sub_
- $mul requires a list, got {type(ranks_data).__name__}
- $abs requires a rank dict, got {type(child_data).__name__}
- $exp requires a rank dict, got {type(child_data).__name__}
- $log requires a rank dict, got {type(child_data).__name__}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/12c04ea219abeedb.
Report an issue: GitHub.