Repository navigation
Description
Summary
On the default SQLite backend, the plugin's MCP server runs with vector search disabled. It does not say so.
The cause is that sqlite-vec is missing from the packages the launcher installs into deps/. The launcher also removes the user site-packages from sys.path, so a user-level pip install sqlite-vec is never seen either.
It gets worse: the store still stamps embedding_model = 'neural' on memories it wrote no vector for. Installing sqlite-vec later does not fix them, because the re-embed worklist only selects rows labelled 'fallback'.
Environment
| OS | Windows 11 Pro 26200 |
| Python | 3.13.4 (C:\Program Files\Python313) |
| Plugin | hypermnesia-mcp@cortex-plugins 4.23.1, git 95f3bec |
| Backend | SQLite (backend.json = {"backend": "sqlite"}) |
| deps dir | ~/.claude/plugins/data/hypermnesia-mcp-cortex-plugins/deps (CLAUDE_PLUGIN_DATA) |
| sqlite-vec | 0.1.9, installed in the user site-packages (AppData\Roaming\Python\Python313\site-packages) |
Defect 1 (root cause): sqlite-vec is not in the launcher's package lists
scripts/launcher_pins.py defines what ensure_deps / ensure_all_deps install into deps/:
BASE_PACKAGES: list[tuple[str, str]] = [
("mcp", "mcp==2.1.1"),
("pydantic", "pydantic==2.13.5"),
("pydantic_settings", "pydantic-settings==2.15.0"),
("numpy", f"numpy=={numpy_version(sys.version_info[:2])}"),
("psycopg", "psycopg[binary]==3.3.5"),
("psycopg_pool", "psycopg_pool==3.3.1"),
("pgvector", "pgvector==0.5.0"),
]ML_PACKAGES holds sentence-transformers, flashrank and torch. Neither list contains sqlite-vec.
The PostgreSQL drivers are installed on every machine. The SQLite extension is installed on none, although SQLite is the zero-config default. pyproject.toml declares it only in the [sqlite] extra, which the plugin install path does not use.
Defect 2: the launcher removes the only place it could come from
scripts/launcher.py drops the user site-packages on purpose. The torch mismatch is a real problem, so the removal itself is reasonable:
_site.addsitedir(deps_dir)
...
if _user_site:
_dropped = os.path.normcase(os.path.abspath(_user_site))
sys.path[:] = [q for q in sys.path
if os.path.normcase(os.path.abspath(q)) != _dropped]The consequence: _try_load_vec() in sqlite_store.py hits ImportError, logs sqlite-vec unavailable … vector search disabled at INFO level, and sets _has_vec = False. Nothing reaches the user.
Defect 3: the model label is written even when no vector is
SqliteMemoryStore._insert_memory_rows stamps the model before checking _has_vec:
if embedding is not None:
self._stamp_embedding_model(memory_id, data.get("embedding_model"))
if self._has_vec:
...INSERT INTO memories_vec...reembed_memory does the same: the vec write is guarded by _has_vec, but _stamp_embedding_model runs anyway.
The _stamp_embedding_model docstring states the precondition "memory_id refers to a just-written vec row". Both callers break it when _has_vec is false.
Result: a row says neural and has no vector. select_fallback_embeddings filters on embedding_model = 'fallback', so this row is never picked up again, even after sqlite-vec becomes available.
Defect 4: nothing surfaces the degraded mode
check_setup/doctorreturnready: true. The SQLite branch only checks that the store opens.consolidatereports"embedding_upgrade": {"upgraded": 86}while 0 vectors were written.
Reproduction
- SQLite backend,
sqlite-vecpresent only in the user site-packages (or nowhere). - Mark rows for re-embedding:
UPDATE memories SET embedding_model='fallback'. - Run
consolidate. - Observe:
embedding_upgrade.upgraded= row count, and every row is nowneural. SELECT count(*) FROM memories_vec_rowids→0.
With sqlite-vec==0.1.9 added to deps/ (pip install --no-deps --target <deps> sqlite-vec==0.1.9), rows re-marked fallback, and the cycle run again: 86 vectors written, and KNN queries return sensible neighbours.
Suggested fixes
- Add
("sqlite_vec", "sqlite-vec==0.1.9")toBASE_PACKAGES. It is small and has no dependencies. - Stamp
embedding_modelonly after the vec row is written. That is the precondition the docstring already states. - Base the re-embed worklist on the vector's absence, not only on the label. For example:
current_memoriesrows with no entry inmemories_vec_rowids. This also repairs stores already mislabelled by defect 3. - On the SQLite backend, make
doctorreport whethersqlite-vecloads, with the fix command. It can stay optional if vector-less operation is a supported mode. - Have
embedding_upgradecount vectors actually written, not rows processed.
Scope
Observed only on Windows. Defect 1 does not depend on the platform: the pin lists are the same everywhere. I have not checked whether sqlite-vec arrives transitively on macOS or Linux.
Workaround
python -m pip install --no-deps --target "$CLAUDE_PLUGIN_DATA/deps" sqlite-vec==0.1.9Then re-mark affected rows fallback and run consolidate.
Activity
fix(ci): drop tomllib from verify_sqlite_extra_parity, 3.10 has none
fix(sqlite): stamp 'neural' only after the vector actually lands
cdeust commentedon Sep 23, 2026
Closing without merging a fix.
A fix was implemented and independently verified on PR #637 (branch
fix/issue-634-sqlite-vec): the root cause you identified (sqlite-vec never named in either dependency-install path the plugin actually uses) is fixed, plus a related stamp-before-write defect found on review (a memory could be mislabelledembedding_model='neural'with no vector actually persisted). Full local test suite green (9121 passed, 11 skipped), ruff and the craftsmanship gate both clean.However, GitHub's
pull_requestevent has never resolved this repository's CI workflow for PR #637, across every attempt tried: repeated pushes, manual workflow dispatch, closing and reopening the PR, and a full delete-and-recreate of the branch. The requiredCI Greenstatus check has never run on that PR.This repository's policy is that nothing merges without a green required CI check, without exception, regardless of how thoroughly a change has been verified by other means. Since that check cannot be produced for this PR, it is not being merged, and this issue is closed on that basis rather than as fixed on
main.Thank you for the detailed, reproducible report. The fix itself remains available on
fix/issue-634-sqlite-vecif the underlying CI-trigger problem is resolved later.fix(setup): persist backend marker before setup.py can fail; close ML…
fix(sqlite): install sqlite-vec on every backend, self-heal vectorles…
ci(windows): target the Windows leg at what actually broke on Windows (…
chore(release): prepare Cortex 4.23.5 (#641)