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

Closed

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.

Activity

  1. added
    editor/integrationEditor compatibility and CLI integration
    parsing/qualityGraph extraction bugs, false positives, missing edges
    ux/behaviorDisplay bugs, docs, adoption UX
    windowsWindows-specific issues
    on Aug 10, 2026
  2. added this to the 0.10.0-rc milestone on Aug 10, 2026
  3. added
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Aug 10, 2026
  4. DeusData commented on Aug 10, 2026

    @DeusData
    Owner

    Thank you again for the exceptionally clear report. We are treating this as critical because the default MCP path can return a silent empty success result. A fix is already actively in progress for the 0.10.1 release, and we will update this thread once the regression tests and implementation are ready.

  5. modified the milestones: 0.10.0-rc, 0.10.1 on Aug 10, 2026
  6. added a commit that references this issue on Aug 11, 2026
  7. DeusData commented on Aug 11, 2026

    @DeusData
    Owner

    Fixed on main in f59d24f (PR #1523, merge 367ba25) — shipping in v0.10.1, releasing now.

    Thank you for an outstanding report, @Navier8. The format-by-format call tables localized the fault to the MCP response path before we had read a line of code, and both bugs reproduced exactly as described — plus your framing of the failure shape ("empty and success-status, indistinguishable from nothing-found") turned out to be the right lens: a verification sweep guided by it found a third bug of the same class (7+ pipelined requests killed the server with all buffered responses lost; fixed in the same PR).

    What shipped for each of your findings:

    • Bug 1 — root cause was an interaction between a wire-size optimization and the declared outputSchema: tree-format replies carried structuredContent: {} while a declared schema tells spec-honoring clients that structuredContent is the result. It reproduced on every platform, not just Windows — your CLI-tree-works observation was the discriminating clue. Tools no longer declare an outputSchema, object payloads keep their parsed structuredContent, text payloads omit the key entirely, and both the unit suite and the shipped-binary smoke suite now assert a default-format reply can never render as {}.
    • Bug 2 — config get now prints the stored value or the key's real runtime default, and unknown keys exit non-zero naming the known keys, on get, set, and reset alike.

    On the DACL note: not reproducible from our side either, but the misattributed config_db_unavailable diagnosis you suggested is a good one — distinguishing permission-denied from locked, with the path included, is on the follow-up list.

    The v0.10.1 release notes credit this report prominently. Thanks again — reports of this quality are rare and genuinely move the project.

  8. DeusData commented on Aug 11, 2026

    @DeusData
    Owner

    v0.10.1 is released with all fixes — https://github.com/DeusData/codebase-memory-mcp/releases/tag/v0.10.1 (GitHub archives, npm, and PyPI are all serving it).

    Verified end-to-end on the shipped binaries, from the seat of a real MCP client (Claude Code):

    • search_graph / trace_path / query_graph / get_architecture / search_code / detect_changes on the default tree format all render full results — no more {}. No tool declares an outputSchema anymore; text payloads carry no structuredContent key at all, object payloads keep the parsed form.
    • Parallel tool-call bursts (tested to 64 pipelined requests) all get answers — the queue now backpressures instead of failing the session.
    • config get returns stored-or-default values, and unknown keys exit 1 naming the known keys, on get/set/reset alike.

    All three contracts are pinned by unit tests, a frontend-queue test, a CLI contract test, and shipped-binary smoke phases that drive the real artifact the way a schema-honoring client does — each verified red against v0.10.0 before the fix.

    @Navier8 — if v0.10.1 behaves in your setup, feel free to close this out (or tell us what still looks off and we'll jump on it). Thanks again for the report that started all of this; the release notes credit it in full.

  9. added
    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then close
    on Aug 11, 2026
  10. github-actions commented on Aug 11, 2026

    @github-actions

    Thanks for the report! To move this forward we need a bit more so we can reproduce it ourselves:

    • the codebase-memory-mcp --version you're on
    • the exact steps or command you ran
    • a public repo (or a small dummy snippet) that shows the problem — please don't paste proprietary code

    Once that's here we'll pick it straight back up. Heads-up: issues left awaiting-reporter are automatically closed after a few weeks of silence, but a comment reopens the door anytime.

  11. DeusData commented on Aug 11, 2026

    @DeusData
    Owner

    Small housekeeping note: please ignore the bot's boilerplate above asking for version/steps — that's our label automation misfiring on this thread (a process bug on our side, noted). Nothing more is needed from you unless v0.10.1 misbehaves in your setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then closebugSomething 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