headroomlabs-ai/headroom · error · ValueError

Query dimension {query_vector.shape[0]} does not match index

Error message

Query dimension {query_vector.shape[0]} does not match index dimension {self._dimension}

What it means

Raised by SQLiteVectorIndex.search when the query vector's length does not equal the index dimension. The sqlite-vec virtual table computes distances in a fixed-dimensional space, so a differently-sized query vector is rejected before the SQL query runs.

Source

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

        """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

                # Get more results than needed for post-filtering
                k_with_buffer = filter.top_k * 10

                # Query sqlite-vec for nearest neighbors
                # sqlite-vec requires 'k = ?' constraint
                # Use subquery to get KNN results first, then join with metadata
                rows = conn.execute(

View on GitHub (pinned to 322425c43b)

Solutions

  1. Assert len(query_vector) == index dimension before searching; log both values on failure.
  2. Pin a single embedder per index/db_path and derive dimension from it everywhere.
  3. If the model legitimately changed, rebuild the index and re-embed all memories.

Example fix

// before
results = await index.search(VectorFilter(query_vector=vec))

// after
if len(vec) != index.dimension:
    raise ValueError(f"query dim {len(vec)} != index dim {index.dimension}")
results = await index.search(VectorFilter(query_vector=vec))
Defensive patterns

Strategy: validation

Validate before calling

if len(filter.query_vector) != index.dimension:
    raise ValueError(f"query dim {len(filter.query_vector)} != index dim {index.dimension}")

Prevention

When it happens

Trigger: Querying with vectors from a different embedding model than the one used at index build time; manually built or reshaped vectors with wrong length; default dimension (384) assumed while the index was created larger.

Common situations: Embedder changed between indexing and searching; multiple models in one app writing to one index; dimension defaults disagreeing across services.

Related errors


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