{"record":{"id":"39f8e58abd164e19","repo":"chroma-core/chroma","slug":"knn-requires-query-field","errorCode":null,"errorMessage":"$knn requires 'query' field","messagePattern":"\\$knn requires 'query' field","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/execution/expression/operator.py","lineNumber":695,"sourceCode":"            raise ValueError(\n                f\"Rank dict must contain exactly one operator, got {len(data)}\"\n            )\n\n        op = next(iter(data.keys()))\n\n        if op == \"$val\":\n            value = data[\"$val\"]\n            if not isinstance(value, (int, float)):\n                raise TypeError(f\"$val requires a number, got {type(value).__name__}\")\n            return Val(value)\n\n        elif op == \"$knn\":\n            knn_data = data[\"$knn\"]\n            if not isinstance(knn_data, dict):\n                raise TypeError(f\"$knn requires a dict, got {type(knn_data).__name__}\")\n\n            if \"query\" not in knn_data:\n                raise ValueError(\"$knn requires 'query' field\")\n\n            query = knn_data[\"query\"]\n\n            if isinstance(query, dict):\n                # SparseVector case - deserialize from transport format\n                if query.get(TYPE_KEY) == SPARSE_VECTOR_TYPE_VALUE:\n                    query = SparseVector.from_dict(query)\n                else:\n                    # Old format or invalid - try to construct directly\n                    raise ValueError(\n                        f\"Expected dict with {TYPE_KEY}='{SPARSE_VECTOR_TYPE_VALUE}', got {query}\"\n                    )\n\n            elif isinstance(query, (list, tuple, np.ndarray)):\n                # Dense vector case - normalize then validate\n                normalized = normalize_embeddings(query)\n                if not normalized or len(normalized) > 1:\n                    raise ValueError(\"$knn requires exactly one query embedding\")","sourceCodeStart":677,"sourceCodeEnd":713,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/execution/expression/operator.py#L677-L713","documentation":"The 'query' field is the only required member of the $knn options dict - it carries the query embedding (dense list/array or serialized SparseVector). Omitting it raises ValueError before anything else is checked; key/limit/return_rank all have defaults ('#embedding', 16, False).","triggerScenarios":"Search(rank={'$knn': {'key': '#embedding', 'limit': 10}}); {'$knn': {}}; renamed or typo'd fields like {'queries': [...]} or {'embedding': [...]} instead of 'query'.","commonSituations":"Integrating with an internal search API whose field names differ; async pipelines where the embedding fetch failed and the field was never attached; copying a $knn example and deleting the query while testing other options.","solutions":["Add the query vector: {'$knn': {'query': emb, ...}}.","Check for exact spelling - the key must be literally 'query'.","If the embedding is unavailable, skip the ranked query (rank=None) instead of sending a stub."],"exampleFix":"# before\nSearch(rank={'$knn': {'key': '#embedding', 'limit': 10}})   # -> ValueError\n\n# after\nSearch(rank={'$knn': {'query': emb, 'key': '#embedding', 'limit': 10}})","handlingStrategy":"validation","validationCode":"if not isinstance(knn_opts, dict) or 'query' not in knn_opts:\n    raise ValueError(\"$knn requires 'query' with exactly one embedding\")\nSearch(rank={'$knn': knn_opts})","typeGuard":"def has_knn_query(knn_opts) -> bool:\n    return isinstance(knn_opts, dict) and 'query' in knn_opts","tryCatchPattern":"try:\n    Search(rank={'$knn': knn_opts})\nexcept (TypeError, ValueError) as e:\n    return bad_request(f'invalid $knn expression: {e}')","preventionTips":["Set 'query' first when building $knn options.","Name the variable holding the embedding 'query' to mirror the wire key.","Fail fast at your API edge when the caller supplies no embedding."],"tags":["validation","valueerror","knn","rank","missing-field","chromadb"],"backgroundTag":"missing-required-field","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}