chroma-core/chroma · error · TypeError
You must provide either queryEmbeddings or queryTexts
Error message
You must provide either queryEmbeddings or queryTexts
What it means
Aggregate.from_dict() (operator.py:1415-1418) requires the aggregate dict to contain exactly one operator entry; two or more raise ValueError with the count. An aggregation strategy is a single choice — keep-k-minimum OR keep-k-maximum — so {"$min_k": {...}, "$max_k": {...}} is ambiguous and rejected rather than guessed. The count is taken on the whole dict (len(data)), and the sole entry must then be '$min_k' or '$max_k' (operator.py:1420-1429).
Source
Thrown at clients/js/packages/chromadb-core/src/Collection.ts:300
queryTexts,
queryEmbeddings,
ids,
}: QueryRecordsParams): Promise<MultiQueryResponse> {
await this.client.init();
let embeddings: number[][] = [];
// If queryEmbeddings is provided, use it
if (queryEmbeddings) {
embeddings = toArrayOfArrays(queryEmbeddings);
}
// If queryTexts is provided, use it to generate queryEmbeddings
else if (queryTexts) {
embeddings = await this.embeddingFunction.generate(toArray(queryTexts));
}
if (embeddings.length === 0) {
throw new TypeError(
"You must provide either queryEmbeddings or queryTexts",
);
}
let filter_ids: string[] | null = null;
if (ids) {
filter_ids = toArray(ids);
}
const resp = await this.client.api.collectionQuery(
this.client.tenant,
this.client.database,
this.id,
nResults,
undefined,
{
query_embeddings: embeddings,
ids: filter_ids,View on GitHub (pinned to aecdd12c8a)
Solutions
- Keep exactly one operator key: {"$min_k": {"keys": ["#score"], "k": 3}}.
- If you merged configs, delete the losing operator so only one entry remains.
- Cannot combine min and max in one aggregate — run two Search queries if you need both orderings.
- Keep metadata/version keys out of the aggregate object; only the operator entry belongs there.
Example fix
// before
aggregate = {"$min_k": {"keys": ["#score"], "k": 3}, "$max_k": {"keys": ["#score"], "k": 3}}
# ValueError: Aggregate dict must contain exactly one operator, got 2
# after
aggregate = {"$min_k": {"keys": ["#score"], "k": 3}} Defensive patterns
Strategy: validation
Validate before calling
def aggregate_single_op(payload: dict) -> bool:
return isinstance(payload, dict) and len(payload) == 1 Type guard
def is_single_operator_aggregate(v: Any) -> TypeGuard[Dict[str, Dict[str, Any]]]:
return (
isinstance(v, dict)
and len(v) == 1
and next(iter(v)) in {"$min_k", "$max_k"}
and isinstance(next(iter(v.values())), dict)
) Try / catch
try:
Aggregate.from_dict(agg)
except ValueError as e:
if "exactly one operator" in str(e):
ops = [k for k in agg if k in ("$min_k", "$max_k")]
agg = {ops[0]: agg[ops[0]]} # keep the first real operator
else:
raise Prevention
- Config merges must replace operator keys, not accumulate them (dict.update replaces only equal keys).
- One ordering per GroupBy — need both min and max? Run two searches.
- Keep version/comment metadata outside the aggregate object.
When it happens
Trigger: {"$min_k": {...}, "$max_k": {...}} — trying to apply both orderings; entries sharing the dict with metadata like {"$min_k": {...}, "version": 2}; merging two aggregate configs with dict.update() so both operators survive; a copy-paste artifact leaving a duplicated operator block.
Common situations: Config systems that merge user overrides over defaults and end up with both operators; authors assuming multiple aggregations compose (they do not — pick one ordering per GroupBy); payloads decorated with extra bookkeeping keys inside the aggregate object; hand-editing examples by adding instead of replacing an operator.
Related errors
- You do not have permission to access the requested resource.
- The requested resource could not be found: ${input}
- ${respBody?.message}
- Failed to fetch ${input} with status ${resp.status}: ${resp.
- Cannot specify both 'hnsw' and 'spann' configurations.
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/709de13c12098474.
Report an issue: GitHub.