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 - distanceView on GitHub (pinned to 322425c43b)
Solutions
- Embed the query first: vec = await embedder.embed(text); search with query_vector=vec.
- Route text searches through a component that owns both an Embedder and the index.
- 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
- Wrap the index with an embedding-aware search service.
- Pass vectors, not text, to raw vector backends.
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
- query_text provided but HNSWVectorIndex does not embed text.
- query_vector must be provided
- Query dimension {query_vector.shape[0]} does not match index
- Either query_vector or query_text must be provided
- Query vector dimension {query_vector.shape[0]} does not matc
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/019552d80be2742b.
Report an issue: GitHub.