{"record":{"id":"709de13c12098474","repo":"chroma-core/chroma","slug":"you-must-provide-either-queryembeddings-or-queryte","errorCode":null,"errorMessage":"You must provide either queryEmbeddings or queryTexts","messagePattern":"You must provide either queryEmbeddings or queryTexts","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/Collection.ts","lineNumber":300,"sourceCode":"    queryTexts,\n    queryEmbeddings,\n    ids,\n  }: QueryRecordsParams): Promise<MultiQueryResponse> {\n    await this.client.init();\n\n    let embeddings: number[][] = [];\n\n    // If queryEmbeddings is provided, use it\n    if (queryEmbeddings) {\n      embeddings = toArrayOfArrays(queryEmbeddings);\n    }\n    // If queryTexts is provided, use it to generate queryEmbeddings\n    else if (queryTexts) {\n      embeddings = await this.embeddingFunction.generate(toArray(queryTexts));\n    }\n\n    if (embeddings.length === 0) {\n      throw new TypeError(\n        \"You must provide either queryEmbeddings or queryTexts\",\n      );\n    }\n\n    let filter_ids: string[] | null = null;\n    if (ids) {\n      filter_ids = toArray(ids);\n    }\n\n    const resp = await this.client.api.collectionQuery(\n      this.client.tenant,\n      this.client.database,\n      this.id,\n      nResults,\n      undefined,\n      {\n        query_embeddings: embeddings,\n        ids: filter_ids,","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/Collection.ts#L282-L318","documentation":"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).","triggerScenarios":"{\"$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.","commonSituations":"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.","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."],"exampleFix":"// before\naggregate = {\"$min_k\": {\"keys\": [\"#score\"], \"k\": 3}, \"$max_k\": {\"keys\": [\"#score\"], \"k\": 3}}\n# ValueError: Aggregate dict must contain exactly one operator, got 2\n\n# after\naggregate = {\"$min_k\": {\"keys\": [\"#score\"], \"k\": 3}}","handlingStrategy":"validation","validationCode":"def aggregate_single_op(payload: dict) -> bool:\n    return isinstance(payload, dict) and len(payload) == 1","typeGuard":"def is_single_operator_aggregate(v: Any) -> TypeGuard[Dict[str, Dict[str, Any]]]:\n    return (\n        isinstance(v, dict)\n        and len(v) == 1\n        and next(iter(v)) in {\"$min_k\", \"$max_k\"}\n        and isinstance(next(iter(v.values())), dict)\n    )","tryCatchPattern":"try:\n    Aggregate.from_dict(agg)\nexcept ValueError as e:\n    if \"exactly one operator\" in str(e):\n        ops = [k for k in agg if k in (\"$min_k\", \"$max_k\")]\n        agg = {ops[0]: agg[ops[0]]}  # keep the first real operator\n    else:\n        raise","preventionTips":["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."],"tags":["chromadb","aggregate","valueerror","schema","min-k","max-k"],"backgroundTag":"dict-schema-validation-failed","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}