Skip to content

fix(core): filter NULL embeddings from vector index build - #993

Merged
ajianaz merged 1 commit into
developfrom
fix/null-embedding-crash-992
Aug 10, 2026
Merged

fix(core): filter NULL embeddings from vector index build#993
ajianaz merged 1 commit into
developfrom
fix/null-embedding-crash-992

Conversation

@ajianaz

@ajianaz ajianaz commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

What

Fix crash where NULL embedding rows in SQLite cause vector_index.build() to fail with dimension mismatch error, blocking server startup and repair_index.

Closes #992.

Why

Memories with NULL embedding silently convert to vec![] via row_to_memory(). When load_all() returns these rows and they reach index.build(), the validator rejects them (0 ≠ 768 dims), crashing the server.

Production data confirmed: 19 NULL embedding rows out of 596 memories (~3.2%).

Changes

  • crud.rsload_all() SQL query: Added WHERE embedding IS NOT NULL to both namespace-filtered and unfiltered variants. This is the primary fix — NULL rows never enter the build pipeline.
  • lib.rs:731-737 — startup index build: Added .filter(|m| !m.embedding.is_empty()) guard before index.build(). Also added if !items.is_empty() check to skip build entirely when all memories have NULL embeddings.
  • maintenance.rs:125-136repair_index: Same defense-in-depth filter applied.
  • crud.rs — regression test: test_load_all_excludes_null_embeddings inserts one valid + one NULL embedding row, asserts load_all() returns only the valid row.

Testing

  • cargo fmt --all
  • cargo clippy --workspace --all-targets ✅ (0 warnings)
  • cargo test --workspace ✅ — 480 pass, 0 fail, 26 ignored (was 479, +1 new test)

Root cause: load_all() returned rows with NULL embedding blobs, which
row_to_memory() silently converted to vec![]. When these reached
index.build(), the dimension validator rejected them (0 != 768),
crashing the server on startup and blocking repair_index.

Fix applied at two levels:
- SQL level: load_all() now filters 'WHERE embedding IS NOT NULL'
- Call sites: lib.rs and maintenance.rs add .filter(|m| !m.embedding.is_empty())
  as defense-in-depth guard before index.build()

Added regression test: test_load_all_excludes_null_embeddings
@ajianaz ajianaz added bug Something isn't working scope:core Core engine work labels Aug 10, 2026
@github-actions

Copy link
Copy Markdown

🔍 Cora AI Code Review

No issues found. Code looks good!


Review powered by cora-code · BYOK · MIT

@ajianaz
ajianaz merged commit 804356c into develop Aug 10, 2026
14 checks passed
@ajianaz
ajianaz deleted the fix/null-embedding-crash-992 branch August 10, 2026 10:16
@ajianaz ajianaz mentioned this pull request Aug 11, 2026
ajianaz added a commit that referenced this pull request Aug 11, 2026
Version bump 0.13.1 → 0.13.2 + CHANGELOG.

Changes since v0.13.1:
- feat: update check (CLI, MCP, HTTP) (#990)
- fix: NULL embeddings crash vector index (#992, #993)
- fix: absolute URL in update check redirect (#994)
- fix: LongMemEval benchmark threshold false negatives (#995, #996)
- chore: branding refresh (#991)

Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working scope:core Core engine work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NULL embedding rows crash vector index build on startup

1 participant