chroma-core/chroma · error · TypeError
$sum requires a list, got {type(ranks_data).__name__}
Error message
$sum requires a list, got {type(ranks_data).__name__} What it means
$sum combines rank expressions and takes a list of at least two rank dicts: {'$sum': [rank1, rank2, ...]}. Passing anything that is not a list/tuple - a dict or bare value - raises TypeError before element validation. $sum/$mul/$max/$min are n-ary list-shaped operators, while $sub/$div take {'left', 'right'} dicts.
Source
Thrown at chromadb/execution/expression/operator.py:754
return_rank = knn_data.get("return_rank", False)
if not isinstance(return_rank, bool):
raise TypeError(
f"$knn return_rank must be a boolean, got {type(return_rank).__name__}"
)
return Knn(
query=query,
key=key,
limit=limit,
default=knn_data.get("default"),
return_rank=return_rank,
)
elif op == "$sum":
ranks_data = data["$sum"]
if not isinstance(ranks_data, (list, tuple)):
raise TypeError(
f"$sum requires a list, got {type(ranks_data).__name__}"
)
if len(ranks_data) < 2:
raise ValueError(
f"$sum 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 == "$sub":
sub_data = data["$sub"]
if not isinstance(sub_data, dict):
raise TypeError(
f"$sub requires a dict with 'left' and 'right', got {type(sub_data).__name__}"View on GitHub (pinned to aecdd12c8a)
Solutions
- Use a list with >= 2 rank dicts: {'$sum': [{'$val': 1}, {'$knn': {...}}]}.
- For two-term subtraction/division switch operators: {'$sub': {'left': ..., 'right': ...}} or '$div'.
- For a single term, drop the wrapper - the child rank alone is the expression.
Example fix
# before
Search(rank={'$sum': {'left': {'$val': 1}, 'right': {'$val': 2}}}) # -> TypeError: got dict
# after
Search(rank={'$sum': [{'$val': 1}, {'$val': 2}]})
# two-term binary alternative
Search(rank={'$sub': {'left': {'$val': 1}, 'right': {'$val': 2}}}) Defensive patterns
Strategy: type-guard
Validate before calling
def rank_sum(*terms):
if len(terms) < 2:
raise ValueError('$sum needs at least 2 ranks')
return {'$sum': list(terms)}
Search(rank=rank_sum({'$val': 1}, {'$knn': {'query': emb}})) Type guard
def is_nary_rank_payload(arg) -> bool:
return (
isinstance(arg, (list, tuple))
and len(arg) >= 2
and all(isinstance(t, dict) for t in arg)
) Prevention
- Memorize the two arities: $sum/$mul/$max/$min take lists; $sub/$div take {'left', 'right'} dicts.
- Build expressions with helper functions or the class API (+, -, *, /) instead of literals.
- A single-term $sum is pointless - pass the term itself.
When it happens
Trigger: Search(rank={'$sum': {'left': {...}, 'right': {...}}}) - using $sub's shape with $sum; {'$sum': {'$val': 1}} trying to 'sum' a single term; {'$sum': 'expr'} passing a string.
Common situations: Mixing up operator arities when hand-writing expressions; template code emitting the same payload shape for every operator; building weighted scores and pairing $sum with a dict by analogy to $sub.
Related errors
- Expected dict for Rank, got {type(data).__name__}
- Rank dict cannot be empty
- Rank dict must contain exactly one operator, got {len(data)}
- $val requires a number, got {type(value).__name__}
- $knn requires a dict, got {type(knn_data).__name__}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/d1d356154ac9b924.
Report an issue: GitHub.