Summary
search_notes returns total: 0 for semantic and hybrid queries even when the current page contains results. The implementation intentionally uses zero as an unknown-total sentinel to avoid a second vector retrieval, but the structured response does not tell clients that the value is unknown.
This caused the 2026-07-16 development MCP acceptance run to classify working pagination as a regression until the source contract was inspected.
Reproduction
- Create at least two searchable notes.
- Call
search_notes(search_type="semantic", page=1, page_size=1, min_similarity=0, output_format="json").
- Call page 2 with the same query.
- Observe distinct results and
has_more=true, while both responses report total: 0.
The same behavior occurs for hybrid search.
Investigation
The behavior is currently intentional:
src/basic_memory/api/v2/routers/search_router.py skips the exact count for non-FTS retrieval, fetches one probe row, and sets total = 0.
src/basic_memory/mcp/tools/search.py documents that vector and hybrid callers should use has_more.
- Existing CLI tests describe the value as an unknown total.
The problem is therefore the machine-readable contract, not retrieval or pagination.
Suggested fix
Represent unknown totals explicitly. Options include:
- Change
total to int | null and return null for non-exact modes.
- Add
total_is_exact: bool or total_status: "exact" | "unknown" while preserving total: 0 temporarily for compatibility.
- Update MCP descriptions, API schemas, CLI rendering, and regression tests together.
Prefer an additive compatibility field first if changing total would break existing clients.
Acceptance criteria
- A structured client can distinguish an exact zero from an unknown total without reading prose documentation.
- Semantic and hybrid pagination continues to use the probe-row strategy and does not add a second vector retrieval.
- Text, title, and permalink searches continue to report exact totals.
- MCP, HTTP API, and CLI tests cover both exact and unknown totals.
Source
Development MCP acceptance run on 2026-07-16. Deployment matched basic-memory revision 796607fdfd0db7a5978d3d07fb71417938ec6bf9.
Summary
search_notesreturnstotal: 0for semantic and hybrid queries even when the current page contains results. The implementation intentionally uses zero as an unknown-total sentinel to avoid a second vector retrieval, but the structured response does not tell clients that the value is unknown.This caused the 2026-07-16 development MCP acceptance run to classify working pagination as a regression until the source contract was inspected.
Reproduction
search_notes(search_type="semantic", page=1, page_size=1, min_similarity=0, output_format="json").has_more=true, while both responses reporttotal: 0.The same behavior occurs for hybrid search.
Investigation
The behavior is currently intentional:
src/basic_memory/api/v2/routers/search_router.pyskips the exact count for non-FTS retrieval, fetches one probe row, and setstotal = 0.src/basic_memory/mcp/tools/search.pydocuments that vector and hybrid callers should usehas_more.The problem is therefore the machine-readable contract, not retrieval or pagination.
Suggested fix
Represent unknown totals explicitly. Options include:
totaltoint | nulland returnnullfor non-exact modes.total_is_exact: boolortotal_status: "exact" | "unknown"while preservingtotal: 0temporarily for compatibility.Prefer an additive compatibility field first if changing
totalwould break existing clients.Acceptance criteria
Source
Development MCP acceptance run on 2026-07-16. Deployment matched
basic-memoryrevision796607fdfd0db7a5978d3d07fb71417938ec6bf9.