headroomlabs-ai/headroom · error · ValueError

query_text provided but SQLiteVectorIndex does not embed tex

Error message

query_text provided but SQLiteVectorIndex does not embed text. Provide query_vector directly or use an Embedder first.

What it means

Raised by SQLiteVectorIndex.search when query_vector is None but query_text is set. This backend performs pure vector search over pre-embedded data and has no text embedding capability; the caller must embed the text externally or pass a vector.

Source

Thrown at headroom/memory/adapters/sqlite_vector.py:662

                        f"DELETE FROM vec_metadata WHERE rowid IN ({placeholders})",
                        rowid_chunk,
                    )

                conn.commit()
                return len(rowids)

    async def search(self, filter: VectorFilter) -> list[VectorSearchResult]:
        """Search for similar vectors.

        Args:
            filter: Search filter with query vector and constraints.

        Returns:
            List of search results sorted by similarity (descending).
        """
        if filter.query_vector is None:
            if filter.query_text is not None:
                raise ValueError(
                    "query_text provided but SQLiteVectorIndex does not embed text. "
                    "Provide query_vector directly or use an Embedder first."
                )
            raise ValueError("query_vector must be provided")

        query_vector = np.asarray(filter.query_vector, dtype=np.float32)
        if query_vector.shape[0] != self._dimension:
            raise ValueError(
                f"Query dimension {query_vector.shape[0]} does not match "
                f"index dimension {self._dimension}"
            )

        with self._lock:
            with self._get_conn() as conn:
                # sqlite-vec returns distance (lower = more similar for L2)
                # For cosine, we need to convert: similarity = 1 - distance
                # But sqlite-vec's cosine distance is already 1 - cosine_similarity
                # So similarity = 1 - distance

View on GitHub (pinned to 322425c43b)

Solutions

  1. Embed the query first: vec = await embedder.embed(text); search with query_vector=vec.
  2. Route text searches through a component that owns both an Embedder and the index.
  3. Standardize on query_vector at the index layer and handle text at a higher layer.

Example fix

// before
results = await index.search(VectorFilter(query_text=q))

// after
results = await index.search(VectorFilter(query_vector=await embedder.embed(q)))
Defensive patterns

Strategy: validation

Validate before calling

if filter.query_vector is None and filter.query_text is not None:
    filter.query_vector = await embedder.embed(filter.query_text)
    filter.query_text = None
results = await index.search(filter)

Prevention

When it happens

Trigger: Calling search with VectorFilter(query_text=...) directly on SQLiteVectorIndex; code ported from a composite service that embedded internally; assuming the filter's text field is supported everywhere.

Common situations: Backend swaps (HNSW facade to raw SQLite index) dropping the embedding step; search handlers built around text input wired straight to the index.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/019552d80be2742b. Report an issue: GitHub.