HarperFast / HarperFast/harper
Detect & fail loudly on embedding dimension mismatch between model and HNSW index
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Problem
HNSW indexes are bound to a specific vector dimension at creation. If a developer starts local development with `nomic-embed-text` (768 dims), populates an index, then later switches to `mxbai-embed-large` (1024 dims), one of two bad things happens:
1. The insert/query fails deep inside HNSW with a low-level dimension error — confusing trace, no actionable message.
2. Worse: it silently succeeds with garbage results because nothing validates the dimension up front.
## Proposal
On schema definition for a vector column with an HNSW index:
- Allow declaring expected dimension: `vector: { type: 'Float32Array', dimensions: 768 }`
- (Already supported? — if so, the rest of this issue is about enforcement consistency)
On `scope.models.embed()` returning a vector that's about to be written into an HNSW-indexed column:
- Validate the dimension at the application layer too — when the result of `embed()` is stored into a column that has declared `dimensions`, throw a clear error:
```
EmbeddingDimensionMismatch: model 'mxbai-embed-large' returned 1024-dim vector,
but column 'Documents.vector' is declared as 768-dim (matching 'nomic-embed-text').
Drop+recreate the index or use a matching embedding model.
```
Bonus: surface a startup warning if the configured default embedding model produces a different dim than any existing HNSW index in the database.
## Why it matters
This is the kind of footgun that doesn't show up in unit tests but bites users at the worst possible time (\"we shipped, now embeddings stopped working in prod\"). Catching it at the schema/embed boundary is dramatically friendlier than catching it inside HNSW.
## Related
- PR #779 (Phase 1 model analytics emission)
- Vector search investigation (host-manager session)
Contributor guide
Assessment
This issue has not been assessed yet.