fix: cap sqlite-vec k value at 4096 to prevent knn query crash

sqlite-vec enforces a hard limit of 4096 on the k parameter in knn
queries. When a project grows beyond 4096 vector chunks the computed
candidate_limit = max(semantic_vector_k, (limit+offset)*10) can exceed
this, causing OperationalError: k value in knn query too large.

Cap candidate_limit at SQLITE_VEC_MAX_K = 4096 inside
SQLiteSearchRepository._run_vector_query() — the one place in the SQLite
backend where k is passed to sqlite-vec. Adds a regression test that
verifies the cap is enforced for a limit value that would otherwise
produce candidate_limit > 4096.

Fixes #604

Co-authored-by: bm-clawd <bm-clawd@users.noreply.github.com>
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
This commit is contained in:
claude[bot]
2026-02-25 05:17:07 +00:00
parent db6d0dcd9e
commit 24f21f8b01
2 changed files with 62 additions and 1 deletions
@@ -28,6 +28,10 @@ from basic_memory.repository.metadata_filters import parse_metadata_filters, bui
from basic_memory.repository.semantic_errors import SemanticDependenciesMissingError
from basic_memory.schemas.search import SearchItemType, SearchRetrievalMode
# sqlite-vec enforces a hard upper limit on the k parameter in knn queries.
# Exceeding this limit raises OperationalError: k value in knn query too large.
SQLITE_VEC_MAX_K = 4096
class SQLiteSearchRepository(SearchRepositoryBase):
"""SQLite FTS5 implementation of search repository.
@@ -444,6 +448,9 @@ class SQLiteSearchRepository(SearchRepositoryBase):
query_embedding: list[float],
candidate_limit: int,
) -> list[dict]:
# sqlite-vec rejects k values above SQLITE_VEC_MAX_K with an OperationalError.
# Cap here so large projects (>4096 chunks) don't crash vector search.
candidate_limit = min(candidate_limit, SQLITE_VEC_MAX_K)
query_embedding_json = json.dumps(query_embedding)
vector_result = await session.execute(
text(