{"record":{"id":"08351d15fd5cc586","repo":"headroomlabs-ai/headroom","slug":"query-vector-must-be-provided","errorCode":null,"errorMessage":"query_vector must be provided","messagePattern":"query_vector must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/memory/adapters/sqlite_vector.py","lineNumber":666,"sourceCode":"                conn.commit()\n                return len(rowids)\n\n    async def search(self, filter: VectorFilter) -> list[VectorSearchResult]:\n        \"\"\"Search for similar vectors.\n\n        Args:\n            filter: Search filter with query vector and constraints.\n\n        Returns:\n            List of search results sorted by similarity (descending).\n        \"\"\"\n        if filter.query_vector is None:\n            if filter.query_text is not None:\n                raise ValueError(\n                    \"query_text provided but SQLiteVectorIndex does not embed text. \"\n                    \"Provide query_vector directly or use an Embedder first.\"\n                )\n            raise ValueError(\"query_vector must be provided\")\n\n        query_vector = np.asarray(filter.query_vector, dtype=np.float32)\n        if query_vector.shape[0] != self._dimension:\n            raise ValueError(\n                f\"Query dimension {query_vector.shape[0]} does not match \"\n                f\"index dimension {self._dimension}\"\n            )\n\n        with self._lock:\n            with self._get_conn() as conn:\n                # sqlite-vec returns distance (lower = more similar for L2)\n                # For cosine, we need to convert: similarity = 1 - distance\n                # But sqlite-vec's cosine distance is already 1 - cosine_similarity\n                # So similarity = 1 - distance\n\n                # Get more results than needed for post-filtering\n                k_with_buffer = filter.top_k * 10\n","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/memory/adapters/sqlite_vector.py#L648-L684","documentation":"Raised by SQLiteVectorIndex.search when the VectorFilter provides neither query_vector nor query_text. Vector similarity search requires a query; constraint-only filters are not a valid 'list all' request for this backend.","triggerScenarios":"Constructing VectorFilter with only metadata constraints (user_id, session_id, time ranges); a nullable query variable defaulting to None and assigned to neither field.","commonSituations":"API endpoints where the query is optional but vector search is unconditional; dynamic filter builders omitting the query key; expecting listing semantics from a similarity index.","solutions":["Require and set a query (embedded to a vector) before calling search.","Validate at the request boundary: reject empty queries with a clear error to the client.","For non-similarity listing, query the metadata store directly instead of the vector index."],"exampleFix":"// before\nresults = await index.search(VectorFilter(user_id=\"u1\"))\n\n// after\nif not query:\n    raise ValueError(\"query required for vector search\")\nresults = await index.search(VectorFilter(query_vector=await embedder.embed(query), user_id=\"u1\"))","handlingStrategy":"validation","validationCode":"if filter.query_vector is None and filter.query_text is None:\n    raise ValueError(\"query required for similarity search\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make the query mandatory in your search handler signature.","Use metadata listing APIs for filter-only reads."],"tags":["sqlite-vec","search","missing-argument","validation"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}