fix(core): load sqlite-vec for embedding-status query - #901
Conversation
After a successful 'bm reindex --embeddings', 'bm project info' still reported "sqlite-vec is unavailable", "Indexed 0/N", and "Chunks 0" and recommended an unnecessary reindex. get_embedding_status() ran the vec0 JOIN count queries on a bare pooled ProjectRepository session that never loaded the sqlite-vec extension, so SQLite raised "no such module: vec0", which the except block mis-reported as unavailable. Add ProjectRepository.scalar_vec_query, which loads sqlite-vec on the session it opens (reusing the project-delete loader) before running a scalar vec0 count, and route the SQLite embeddings/orphan JOIN queries through it. The except block now only handles the genuinely-missing-dependency case (e.g. python.org builds without enable_load_extension). Adds a real-vec0 integration regression test and updates the unit test to simulate sqlite-vec failing to load via scalar_vec_query returning None. Closes #658 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 66ca306bb3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| project_id=project_id, | ||
| app_config=app_config, | ||
| ) | ||
| await search_repo._ensure_vector_tables() |
There was a problem hiding this comment.
Skip real vec0 test when extension loading is unavailable
On SQLite environments where the Python build exposes sqlite_vec but cannot enable/load SQLite extensions, this new regression test fails at setup before it reaches the status fallback path (I reproduced this with uv run pytest test-int/semantic/test_embedding_status_vec0.py -q, which raises AttributeError: 'sqlite3.Connection' object has no attribute 'enable_load_extension'). Since the codebase explicitly supports degrading in that scenario, the test should probe the capability and skip when real vec0 tables cannot be created rather than making the suite fail on those interpreters.
Useful? React with 👍 / 👎.
|
Claude finished @phernandez's task in 2m 11s —— View job PR Review: fix(core): load sqlite-vec for embedding-status query
|
Windows SQLite Integration (job 79984353954) and both review bots flagged test-int/semantic/test_embedding_status_vec0.py: it builds a REAL vec0 table during setup, which fails on Python builds lacking enable_load_extension (python.org macOS / some Windows interpreters) with AttributeError. The codebase already degrades gracefully there, so probe the capability and pytest.skip when extension loading is unavailable — an environment-capability skip, not silencing a bug. Also addresses claude-review: add the missing Executable type annotation on ProjectRepository.scalar_vec_query's 'query' parameter (matches the type the base Repository.execute_query already uses); ty check passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task in 1m 21s —— View job PR Review: fix(core): load sqlite-vec for embedding-status queryTasks:
Follow-up Review (commit
|
…ftest test-int/semantic/conftest.py spins up a pgvector testcontainer for its benchmark fixtures, so the new vec0 regression test triggered Docker (ryuk) during setup and ERRORed on the Windows SQLite-only CI job (no Docker). Move it to test-int/ so it uses the root SQLite engine_factory (no Docker); the enable_load_extension skip-probe still covers python.org/Windows builds without extension loading. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task in 1m 40s —— View job PR Review: fix(core): load sqlite-vec for embedding-status queryTasks:
Follow-up Review (commit
|

Summary
After a successful
bm reindex --embeddings,bm project infostill reported "sqlite-vec is unavailable", showed "Indexed 0/N" and "Chunks 0", and recommended an unnecessary reindex (#658). Vector search itself worked fine — only the status report was wrong.Root cause:
ProjectService.get_embedding_status()runs thevec0count queries (thesearch_vector_chunksJOINsearch_vector_embeddings) viaProjectRepository.execute_query, which opens a bare pooled session that never loads the sqlite-vec extension. SQLite then raisesno such module: vec0, and theexcept SAOperationalErrorblock mapped that tovector_tables_exist=False+reindex_recommended=True— the false "unavailable". This is SQLite-only; the Postgres branch is unaffected.What changed
repository/project_repository.py: addedscalar_vec_query(), which opens a scoped session, loads sqlite-vec on it via the existing_load_sqlite_vec_on_sessionloader (the same one used by project delete), then runs a scalarCOUNTquery. ReturnsNoneonly when sqlite-vec genuinely cannot be loaded on this Python build (e.g. python.org macOS withoutenable_load_extension).services/project_service.py: the SQLite embeddings/orphan JOIN counts now go throughscalar_vec_query(consolidated in a small_vec_scalarclosure). When it returnsNonethe code raises the canonicalno such module: vec0so the existingexceptblock still emits the true "sqlite-vec unavailable" message — now only for the genuinely-missing-dependency case, not the normal path. The Postgres branch is unchanged (still usesexecute_query).tests/services/test_project_service_embedding_status.py: updated the "unavailable" unit test to simulate the failure viascalar_vec_queryreturningNone(the new signal), since the JOIN no longer flows throughexecute_query.Testing
New integration test
test-int/semantic/test_embedding_status_vec0.pybuilds a realvec0virtual table, writes a real embedding into it via the search repository, disposes the connection pool (so the vec-loaded connection is evicted), then callsget_embedding_statusthrough a freshProjectRepositorythat never loaded the extension — the exact #658 condition. It assertsvector_tables_exist=True,reindex_recommended=False, and correct Indexed/Chunks/Embeddings counts. Verified the test fails on the pre-fix code (reportsvector_tables_exist=False+ "sqlite-vec is unavailable") and passes with the fix.Risk / validation
execute_query).scalar_vec_queryreturnsNoneand the code re-raisesno such module: vec0into the sameexceptblock, so the existing graceful "install/update basic-memory" message still appears.project infocall, not a hot path.Closes #658
🤖 Generated with Claude Code