headroomlabs-ai/headroom · error · ValueError
Embedding dimension {embedding.shape[0]} does not match inde
Error message
Embedding dimension {embedding.shape[0]} does not match index dimension {self._dimension} What it means
Raised by HNSWVectorIndex.add_memory when the supplied embedding's length differs from the dimension the index was constructed with (self._dimension). HNSW graphs have a fixed vector size at creation, so any vector of a different length is rejected before insertion.
Source
Thrown at headroom/memory/adapters/hnsw.py:338
async def index(self, memory: Memory) -> None:
"""Index a memory's embedding for similarity search.
The memory must have an embedding set. If max_entries is set and
the limit is reached, low-importance entries are evicted.
Args:
memory: The memory to index.
Raises:
ValueError: If the memory has no embedding or wrong dimension.
"""
if memory.embedding is None:
raise ValueError(f"Memory {memory.id} has no embedding")
embedding = np.asarray(memory.embedding, dtype=np.float32)
if embedding.shape[0] != self._dimension:
raise ValueError(
f"Embedding dimension {embedding.shape[0]} does not match "
f"index dimension {self._dimension}"
)
with self._lock:
# Check if already indexed - update if so
if memory.id in self._memory_to_hnsw:
await self._update_embedding_internal(memory.id, embedding)
# Update metadata
self._metadata[memory.id] = IndexedMemoryMetadata.from_memory(memory)
else:
# Evict if at capacity (before adding new entry)
if self._max_entries is not None:
current_size = len(self._memory_to_hnsw)
if current_size >= self._max_entries:
self._evict_entries(self._eviction_batch_size)
# Resize HNSW index if needed (separate from entry limit)View on GitHub (pinned to 322425c43b)
Solutions
- Print/inspect embedding.shape[0] and the index dimension, then recreate the index with dimension matching your Embedder output.
- If the model changed, rebuild the index from scratch (re-embed all memories) — you cannot mix dimensions in HNSW.
- Centralize the dimension: derive index dimension from embedder.dimension instead of a hardcoded literal.
Example fix
// before index = HNSWVectorIndex(dimension=384) await index.add_memory(memory) # embedder returns 768-dim // after index = HNSWVectorIndex(dimension=embedder.dimension) await index.add_memory(memory)
Defensive patterns
Strategy: validation
Validate before calling
dim = np.asarray(memory.embedding).shape[0]
if dim != index.dimension:
raise RuntimeError(f"embedder dim {dim} != index dim {index.dimension}") Prevention
- Construct the index with dimension=embedder.dimension, never a hardcoded literal.
- Add an integration test asserting a fresh embedder output fits the configured index.
When it happens
Trigger: Index created with dimension=384 but the Embedder produces 768-dim vectors (e.g. switching MiniLM to a larger model); mixing embeddings from different providers in one index; loading an index saved with another dimension.
Common situations: Changing embedding model without rebuilding the index; copy-pasting a dimension constant that no longer matches the model; using a default dimension while embedding with a non-default model.
Related errors
- Memory {memory.id} has no embedding
- Query vector dimension {query_vector.shape[0]} does not matc
- Embedding dimension {embedding.shape[0]} does not match inde
- query_text provided but HNSWVectorIndex does not embed text.
- Either query_vector or query_text must be provided
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/e28f5c4062d504a0.
Report an issue: GitHub.