chroma-core/chroma · error · Error
No API key provided
Error message
No API key provided
What it means
Aggregate.from_dict() (operator.py:1412-1413) raises ValueError when given an empty dict {}. An Aggregate dict must name exactly one operator ('$min_k' or '$max_k') whose value carries the keys/k parameters; an empty mapping names none, so there is nothing to construct and the decoder refuses it. This differs deliberately from GroupBy.from_dict, where {} is legal and means 'no grouping' (operator.py:1514-1515) — empty is meaningful for GroupBy but meaningless for Aggregate.
Source
Thrown at clients/js/packages/chromadb-core/src/CloudClient.ts:28
tenant?: string;
cloudHost?: string;
cloudPort?: string;
}
class CloudClient extends ChromaClient {
constructor({
apiKey,
database,
tenant,
cloudHost,
cloudPort,
}: CloudClientParams) {
// If no API key is provided, try to load it from the environment variable
if (!apiKey) {
apiKey = process.env.CHROMA_API_KEY;
}
if (!apiKey) {
throw new Error("No API key provided");
}
cloudHost = cloudHost || "https://api.trychroma.com";
cloudPort = cloudPort || "8000";
const path = `${cloudHost}:${cloudPort}`;
const auth: AuthOptions = {
provider: "token",
credentials: apiKey,
tokenHeaderType: "X_CHROMA_TOKEN",
};
return new ChromaClient({
path: path,
auth: auth,
database,
tenant,View on GitHub (pinned to aecdd12c8a)
Solutions
- Fill in a real aggregation: {"aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}} (top-3 per group by relevance).
- If you intended no grouping at all, use group_by={} (or omit it) — not an empty aggregate.
- Make your config layer reject or default an empty aggregate section instead of forwarding {}.
- Remember the two legal aggregate operators are exactly '$min_k' and '$max_k' (operator.py:1422-1429).
Example fix
// before
group_by = {"keys": ["category"], "aggregate": {}}
# ValueError: Aggregate dict cannot be empty (via GroupBy.from_dict)
# after
group_by = {"keys": ["category"], "aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}} Defensive patterns
Strategy: validation
Validate before calling
def aggregate_not_empty(payload: dict) -> bool:
return isinstance(payload, dict) and len(payload) > 0 Type guard
def is_nonempty_aggregate(v: Any) -> TypeGuard[Dict[str, Any]]:
return isinstance(v, dict) and len(v) == 1 and next(iter(v)) in {"$min_k", "$max_k"} Try / catch
try:
Aggregate.from_dict(agg)
except ValueError as e:
if "cannot be empty" in str(e):
# decide intent: no grouping, or a missing aggregation spec
raise ValueError("group_by aggregate cannot be {}; omit group_by for "
"no grouping, or supply {'$min_k': {...}}") from e
raise Prevention
- {} means 'no grouping' only at the group_by level, never inside aggregate.
- Make config schemas require a non-empty aggregate body when the section exists.
- Prevent builders from emitting aggregate: {} placeholders.
When it happens
Trigger: GroupBy.from_dict({"keys": ["category"], "aggregate": {}}) — an explicitly empty aggregate alongside real keys; Aggregate.from_dict({}) direct calls; config templating that emits aggregate: {} when the user left the aggregation section blank; merging configs where all aggregate entries were filtered out.
Common situations: Config schemas that require an aggregate key but let it be empty; builders that initialize aggregate = {} and forget to fill it; authors copying the GroupBy empty-dict idiom into aggregate; JSON merge tools that strip unknown operators and leave {} behind.
Related errors
- Invalid HNSW config provided
- Unauthorized
- You do not have permission to access the requested resource.
- The requested resource could not be found: ${input}
- ${respBody?.message}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/67698ea5fbce87cb.
Report an issue: GitHub.