chroma-core/chroma · error · ChromaUniqueError
The resource already exists
Error message
The resource already exists
What it means
_parse_k_aggregate() (operator.py:1363-1365) requires the 'keys' field inside a '$min_k'/'$max_k' aggregation to be a list or tuple; anything else raises TypeError with the offending type name. The aggregation ranks records on these keys per group (e.g. ["#score"] or ["priority", "#score"]), and _strings_to_keys (operator.py:1334-1336) iterates it element-wise — a scalar or dict cannot supply an ordered ranking key set. Unlike Select.from_dict, a set is not accepted here because multi-key aggregation order is significant.
Source
Thrown at clients/js/packages/chromadb-core/src/ChromaFetch.ts:77
throw error;
}
switch (resp.status) {
case 400:
throw new ChromaClientError(
`Bad request to ${input} with status: ${resp.statusText}`,
);
case 401:
throw new ChromaUnauthorizedError(`Unauthorized`);
case 403:
throw new ChromaForbiddenError(
`You do not have permission to access the requested resource.`,
);
case 404:
throw new ChromaNotFoundError(
`The requested resource could not be found: ${input}`,
);
case 409:
throw new ChromaUniqueError("The resource already exists");
case 422:
if (
respBody?.message &&
(respBody?.message.startsWith("Quota exceeded") ||
respBody?.message.startsWith("Billing limit exceeded"))
) {
throw new ChromaQuotaExceededError(respBody?.message);
}
break;
case 500:
throw parseServerError(respBody?.error);
case 502:
case 503:
case 504:
throw new ChromaConnectionError(
`Unable to connect to the chromadb server. Please try again later.`,
);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Wrap keys in a list: {"$min_k": {"keys": ["#score"], "k": 3}}.
- If you hold a Python set from a Select, convert it: {"keys": list(select_keys)} before embedding it in an aggregate.
- Use '#score' (mapped to Key.SCORE by _strings_to_keys) or plain metadata field names as string elements.
- For multi-key ranking keep the order meaningful: ["priority", "#score"] ranks by priority first, score as tiebreaker.
Example fix
// before
aggregate = {"$min_k": {"keys": "#score", "k": 3}} # TypeError: $min_k keys must be a list, got str
# after
aggregate = {"$min_k": {"keys": ["#score"], "k": 3}} Defensive patterns
Strategy: type-guard
Validate before calling
def agg_keys_is_list(payload: dict) -> bool:
op = next(iter(payload))
body = payload.get(op, {})
return isinstance(body, dict) and isinstance(body.get("keys"), (list, tuple)) Type guard
def is_wellformed_k_aggregate(v: Any) -> TypeGuard[Dict[str, Dict[str, Any]]]:
if not (isinstance(v, dict) and len(v) == 1):
return False
op, body = next(iter(v.items()))
return (
op in {"$min_k", "$max_k"}
and isinstance(body, dict)
and isinstance(body.get("keys"), (list, tuple))
and bool(body.get("keys"))
and isinstance(body.get("k"), int)
and not isinstance(body.get("k"), bool)
and body["k"] > 0
) Try / catch
try:
Aggregate.from_dict(agg)
except TypeError as e:
if "keys must be a list" in str(e):
op = next(iter(agg))
ks = agg[op]["keys"]
agg[op]["keys"] = [ks] if isinstance(ks, str) else list(ks)
else:
raise Prevention
- Aggregate keys accept list/tuple only — sets are legal for Select but not here (order matters).
- Convert collections from Select contexts: list(...) before reuse.
- Bracket single keys: ['#score'], not '#score'.
When it happens
Trigger: {"$min_k": {"keys": "#score", "k": 3}} — single string not wrapped in a list; {"keys": {"key": "#score"}} — object form from JSON config; {"keys": null}; passing a Python set — accepted by Select.from_dict but rejected here, so reusing a select payload's keys for the aggregate fails.
Common situations: Single-key aggregations written without brackets; JSON configs using an object because a config system cannot express empty/typed arrays; single-element arrays collapsed to scalars by intermediate serializers; porting a Select payload (where set/tuple are fine) into an aggregate.
Related errors
- Unable to connect to the chromadb server. Please try again l
- Failed to connect to chromadb. Make sure your server is runn
- Unauthorized
- You do not have permission to access the requested resource.
- The requested resource could not be found: ${input}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/227e3f9b68f7cbb1.
Report an issue: GitHub.