Skip to content

query_graph / search_graph return "project not found" inconsistently; DBs valid on disk but CLI looks up wrong inode #704

Description

@MatiasNAmendola

query_graph / search_graph return "project not found or not indexed" even with a registered, indexed project

Environment

  • Tool: codebase-memory-mcp v0.8.1 (binary download from release, macOS aarch64)
  • OS: macOS 15 (Darwin), APFS filesystem (default case-insensitive, case-preserving)
  • Storage dir: ~/.cache/codebase-memory-mcp/
  • Project indexed: MSBA-MSBA (3034 .cs files, 82,303 nodes / 269,108 edges per list_projects)

Repro

  1. Install cbm 0.8.1 per the official script (single static binary).
  2. Index a repo: codebase-memory-mcp cli index_repository '{"repo_path":"/path/to/MSBA-MSBA"}' — succeeds, list_projects shows it.
  3. Within the same shell session (or the same batch job that called index_repository), run:
    codebase-memory-mcp cli search_graph '{"name_pattern":"DTO$","label":"Class","limit":100,"project":"Users-...-MSBA-MSBA"}'
    → returns 35 results, exit=0.
  4. Wait 10 minutes (or close/reopen the shell).
  5. Run the exact same command again → {"error":"project not found or not indexed", "available_projects":[...the same 4 entries...]}

What's odd

  • list_projects keeps showing the project (full nodes/edges/size_bytes metadata present).
  • _config.db is empty (SELECT * FROM config → 0 rows in ~/.cache/codebase-memory-mcp/_config.db).
  • The per-project SQLite DB (Users-...-MSBA-MSBA.db, ~282 MB) is still on disk, populated, the same content as before — file reports it as a valid SQLite 3.x database.
  • Trying codebase-memory-mcp config set project "<name>" and config reset project does not change anything.
  • Tried 8 variations of the project parameter naming (project, project_name, project_id, projectName, projectPath, root_path) — every form is rejected with the same error.

Smell-test observations from a CI run on 2026-06-29

I ran a 120-combo benchmark (3 tools × 4 repos × 10 probes) using cbm via the same CLI wrapper. During the run (~7 min), all search_graph/query_graph calls inside the bench returned 200-class responses with parsed matches; 5 minutes after the run finished, the exact same CLI invocations started failing.

I noticed two files with display name Users-...-MSBA-MSBA.db in the cache dir, differing only in character class:

inode size path byte sequence
100978290 295895040 ...matias.nah**u**el**.amendola**-Projects-...-MSBA-MSBA.db (note the . after el)
101033163 0 ...matias.nah**u**el**-amendola**-Projects-...-MSBA-MSBA.db (note the - after el)

So list_projects returns 5 entries (one of them is the empty …el-amendola… path), and query_graph "knows about" the populated project (Users-...-MSBA-MSBA.db) but the second …el-amendola… shadow-DB confuses the lookup.

This appears to be a filesystem path normalization issue (Unicode NFD/NFC? Or HFS+'s case-insensitivity creation semantics?) where the CLI picks up a different on-disk file depending on how the path is being passed (env-var vs cmdline-arg vs working-dir-relative), and the wrong one wins.

Probable root cause

The CLI binary must be doing one of:

  1. realpath() on the project argument, then normalizing against an HFS-/APFS-canonical form different from what was used during index time.
  2. Comparing only by display_name (which collides under case-insensitive filesystems) rather than inode/path.
  3. Maintaining an in-memory registry that's only consistent within a single process (the bench's per-process state had the right pointer; subsequent fresh processes have a different one).

Evidence

Bench JSON proving the query path worked once:

  • cbm-MSBA-MSBA-inconsistency_dto_rename.json → 35 matches with qualified_name populated, exit_code=0, command=[...cli, search_graph, '{\"name_pattern\": \"DTO$\", \"label\": \"Class\", \"limit\": 100, \"project\": \"Users-...-MSBA-MSBA\"}']

After the run, the same command returns:

  • exit_code=1, stderr={"error":"project not found or not indexed","hint":"Use list_projects...","available_projects":["...", "...", ..., "Users-...-MSBA-MSBA"]}

What I'd like

A fix (or workaround doc) for one of:

  1. CLI: cache the project registry to disk so it survives process boundaries.
  2. Path normalization: canonicalize project paths the same way at index and query time (suggested: compare by inode/mtime, not path bytes).
  3. Workaround doc: how to invoke cbm CLI so the project lookup is robust against the in-memory-only registry.

Environment

$ codebase-memory-mcp --version
codebase-memory-mcp 0.8.1

$ uname -a
Darwin Mac 24.x ... aarch64

Thanks — happy to test any fix on my end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcypherCypher query language parser/executor bugsux/behaviorDisplay bugs, docs, adoption UX

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions