Skip to content

0.10.0: two silent empty-result paths — tree format returns {} over MCP (default), and config get returns empty for all keys but auto_index #1522

Description

@Navier8

Two independent v0.10.0 bugs that share a failure shape: both return an empty result with a success status instead of either data or an error. Filing together because that shape is the actionable part — for an LLM client, "empty" and "nothing found" are indistinguishable, so both produce silent false conclusions rather than visible failures. Happy to split into two issues if you'd prefer.

Environment

  • codebase-memory-mcp 0.10.0, windows-amd64 release zip
  • Windows 11 (26100), installed to a custom --dir
  • MCP client: Claude Code (stdio)
  • Project indexed with --mode full, status: ready, 4770 nodes / 21837 edges, parse_partial: 0, skipped: 0

Bug 1 — format: "tree" returns bare {} over MCP (default format, so every naive call is affected)

search_graph and trace_path return an empty JSON object {} over the MCP transport whenever the output format is tree. Since tree is the default, an ordinary call with no format argument silently yields nothing. The identical query with format: "json" returns full, correct results, so the query engine and the index are fine — it looks isolated to the MCP-side tree encoder.

Critically, the same tree format renders correctly over the CLI, which is what localizes this to the MCP response path rather than the formatter itself.

Reproduction

Same binary, same index, same project, four consecutive calls:

# Call Result
1 search_graph(project=P, name_pattern="_build_and_push_graph") — no format {}
2 search_graph(project=P, name_pattern="_build_and_push_graph", format="tree") {}
3 search_graph(project=P, name_pattern="_build_and_push_graph", format="json") correct, total: 2
4 trace_path(project=P, function_name="similarity_edge_key", mode="calls", direction="inbound") — no format {}
5 same as 4 with format="json" correct, callers_total: 3

Call 3 output (abridged):

{"total":2,"count":2,"cols":["name","label","lines","in","out"],
 "groups":[{"qn_prefix":"<project>.<pkg>.main","file":"<pkg>/main.py",
            "rows":[["_build_and_push_graph","Function","1457-1936",6,66]]}],
 "has_more":false}

Call 5 output:

{"function":"similarity_edge_key","direction":"inbound","mode":"calls",
 "callers_total":3,
 "callers":{"cols":["name","hop"],"groups":[
   {"qn_prefix":"<project>.<pkg>.graph.builder","rows":[["to_graphology_json",1]]},
   {"qn_prefix":"<project>.<pkg>.main","rows":[["_build_and_push_graph",2]]}]}}

CLI contrast — tree works here

$ codebase-memory-mcp cli search_graph --project <P> --name-pattern "_build_and_push_graph"
total: 2
results: 2  (rows: name label lines in out; qn = group prefix + "." + name)
<project>.<pkg>.main (<pkg>/main.py):
  _build_and_push_graph Function 1457-1936 6 66
<project>.<pkg>.tests.test_exceptions (<pkg>/tests/test_exceptions.py):
  test_r3_cache_key_construction_matches_build_and_push_graph_source Function 356-370 0 1
has_more: false

Explicit --format tree over the CLI is identical. So: CLI tree ✅, MCP tree ❌, MCP json ✅.

Why this one is worse than it looks

{} is indistinguishable from a genuine zero-result search. An agent following the server's own instructions ("use graph tools first for structural code discovery") will conclude a symbol has no callers, or does not exist, and fall back to grep or to an assumption — with no error anywhere to signal that the answer was wrong. The failure is silent, and it hits the default code path.

Suggested fix, in preference order: fix the MCP tree encoder; failing that, return an explicit error rather than {} when encoding yields nothing, so callers can distinguish "no matches" from "could not encode".


Bug 2 — config get returns empty with exit 0 for every key except auto_index

config get <key> prints a value only for auto_index. Every other valid key returns an empty string and exit code 0 — as does a deliberately invalid key, so a typo is indistinguishable from a correctly-read setting.

Reproduction

$ for k in auto_index auto_watch auto_index_limit ui-lang totally_bogus_key; do
    printf '%-20s -> [%s] exit=%s\n' "$k" "$(codebase-memory-mcp config get $k)" "$?"
  done

auto_index           -> [true]  exit=0
auto_watch           -> []      exit=0
auto_index_limit     -> []      exit=0
ui-lang              -> []      exit=0
totally_bogus_key    -> []      exit=0

config list reports all four correctly in the same session, so the values are stored and readable — it is the get path that drops them:

Configuration:
  auto_index                = true
  auto_index_limit          = 50000
  auto_watch                = true
  ui-lang                   = auto

Expected: config get auto_watch prints true; an unknown key exits non-zero with an error naming the key.


Note on how these were found

Surfaced while verifying an 0.8.1 → 0.10.0 upgrade. Unrelated to both, but worth flagging in case others hit it during the same upgrade: every .db in the data dir had been left with an empty DACL on Windows (D:AI, zero ACEs), which made the daemon fail at startup with

level=error msg=daemon.runtime_config_open_failed reason=config_db_unavailable
level=error msg=daemon.start_failed component=application

while every client reported the misleading CBM daemon is active or starting but could not accept this client within 30000 ms — because the dead daemon left its lock files behind. I could not determine what stripped the ACLs and cannot attribute it to this project; files recreated by 0.10.0 get correct ACEs (SYSTEM full, logon-session read/execute, owner full), so this is not a reproducible bug report. The only suggestion worth making is that config_db_unavailable would be far easier to diagnose if it distinguished "permission denied" from "locked" and included the path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeditor/integrationEditor compatibility and CLI integrationparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.ux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions