Fix list_projects empty + trace_path qualified-name lookup#298
Fix list_projects empty + trace_path qualified-name lookup#298nv-jwiley wants to merge 1 commit intoDeusData:mainfrom
Conversation
Two related bugs surfaced during a real-world tool sweep against an orca install (DGX Spark agent platform). Both patches are in src/mcp/mcp.c, the in-process MCP request handler. 1) list_projects returned an empty array even when projects were indexed and queryable. Root cause: is_project_db_file() (mcp.c:846, also duplicated inline in collect_db_project_names at mcp.c:791) excluded any filename with a "tmp-" prefix. But cbm_project_name_from_path() legitimately produces "tmp-..." project names for source roots under /tmp/ (covered by tests/test_pipeline.c:1903 — "/tmp/bench/erlang/lib/ stdlib/src" → "tmp-bench-erlang-lib-stdlib-src"). Any project rooted under /tmp got silently filtered from list_projects + the "available_projects" hint inside build_project_list_error. Fix: drop the "tmp-" prefix exclusion entirely. SQLite's actual journal/WAL files end with `-journal`, `-wal`, `-shm` (not `.db`) and never collide with the `.db` suffix the function already requires, so removing the prefix filter is safe. While here, refactor collect_db_project_names() to call is_project_db_file() so the filter logic lives in one place. 2) trace_path returned "function not found" when called with a fully-qualified function name like "Users-foo-dev-myrepo.src.module.func". Root cause: handle_trace_call_path() (mcp.c:1887) only called cbm_store_find_nodes_by_name(), which queries `WHERE name = ?2` (the bare name column). The tool's own error hint tells callers to "fully qualify" the name, but doing so caused the lookup to miss every time. Fix: when the bare-name lookup returns 0 nodes, fall back to cbm_store_find_node_by_qn() (already exists in store.c). If that resolves, wrap the single result into the same nodes[] array the downstream BFS expects, so the rest of the function is unchanged. Verified locally on macOS arm64 against a real 12,770-node /36,859-edge mode=full index — list_projects now lists all projects (including tmp-rooted ones), and trace_path with a fully-qualified name returns identical callees/callers to the bare-name lookup.
|
Thanks @nv-jwiley — both diagnoses are spot on, both root causes are correctly identified, and the fixture you cited ( Landed on
Why two commits instead of merging the PR directly: the branch base is from April 16, and Closing the PR — both fixes are now on |
Summary
Two bugs in
src/mcp/mcp.csurfaced during a real-world MCP tool sweep against amode=fullindex of a 12,770-node Python repo on macOS arm64. Both have minimal, targeted fixes.Bug 1 —
list_projectsreturns{"projects":[]}even when projects existSymptom: After
index_repository(...)succeeds, the project is fully queryable viaindex_status,search_code,search_graph,query_graph,get_code_snippet,trace_path, etc., butlist_projectsreturns an empty array.Root cause:
is_project_db_file()(mcp.c:846, also inlined insidecollect_db_project_namesat mcp.c:791) excludes any filename with atmp-prefix. Butcbm_project_name_from_path()legitimately producestmp-...project names for source roots under/tmp/— verified by an existing in-tree test:Any project rooted under
/tmpwas silently filtered fromlist_projects+ theavailable_projectshint insidebuild_project_list_error.Fix: drop the
tmp-prefix exclusion entirely. SQLite's actual journal/WAL sidecar files end with-journal,-wal,-shm(not.db) and never collide with the.dbsuffixis_project_db_filealready requires, so removing the prefix filter is safe. While here, refactorcollect_db_project_names()to callis_project_db_file()so the filter lives in one place.Bug 2 —
trace_pathreturnsfunction not foundfor fully-qualified namesSymptom: Calling
trace_pathwith a fully-qualified function name ("<project>.module.submodule.func") returns{"error":"function not found", ...}even when the node exists. The tool's own error hint instructs callers to "fully qualify" the name, but doing so causes the lookup to miss every time — the documented "fully qualify for precise match" UX inverts what actually works.Root cause:
handle_trace_call_path()(mcp.c:1887) only callscbm_store_find_nodes_by_name(), which queriesWHERE project = ?1 AND name = ?2against the barenamecolumn. The qualified name is never tried.Fix: when the bare-name lookup returns 0 nodes, fall back to
cbm_store_find_node_by_qn()(already exists in store.c, used elsewhere). If that resolves, wrap the single result into the samenodes[]array the downstream BFS expects, so the rest of the function is unchanged.Verification
Built locally with
make -f Makefile.cbm cbm, replaced the cached binary at~/Library/Caches/codebase-memory-mcp/0.6.0/codebase-memory-mcpon macOS arm64, restarted the host service, and verified against a realUsers-jwiley-dev-orcaindex (12,770 nodes / 36,859 edges) plus a synthetictmp-cbm_sandboxproject rooted at/tmp/cbm_sandbox:Pre-patch:
list_projectsreturned{"projects":[]}.Post-patch: returns both
tmp-cbm_sandboxandUsers-jwiley-dev-orca.Pre-patch:
trace_path(function_name="Users-jwiley-dev-orca.src.services.session_enricher.enrichment_service.run_enrichment")returnedfunction not found.Post-patch: returns identical
callees(29 nodes across hops 1+2) andcallers(2 nodes) to the bare-name lookuptrace_path(function_name="run_enrichment").Existing tests untouched.
Test plan
-O2 -Wall -Wextra -Werroron macOS arm64list_projectsnow surfaces atmp-cbm_sandboxproject (was previously filtered)trace_pathwith bare name (control) still workstrace_pathwith fully-qualified name returns identical traversalmake -f Makefile.cbm test)