Skip to content

Projects with a ::missed shadow row vanish from list_projects and the graph UI #1044

Description

@metehanulusoy

Summary

Any project whose db carries a <name>::missed shadow row (created by the miss-graph feature for projects with at least one parse/index failure — i.e. most real-world repos) disappears from list_projects and the graph UI, even though the index is complete and directly-addressed tools (search_graph, index_status, get_graph_schema) keep working.

Observed on a real repo: a 704-file ASP.NET codebase indexed fine (70,410 nodes / 308,106 edges, index_statusready), but list_projects returned {"projects":[]} and the UI showed "No indexed projects".

Environment

Root cause

Two features conflict:

  1. The miss-graph pass inserts a second row into the per-db projects table — <project>::missed — because nodes.project has an FK to projects(name). The comment there still claims this row is "Invisible to list_projects, which scans the cache directory for .db files, not this table" (src/store/store.c#L1983-L1986) — that claim is stale since query_graph / search_graph return "project not found" inconsistently; DBs valid on disk but CLI looks up wrong inode #704.
  2. Since query_graph / search_graph return "project not found" inconsistently; DBs valid on disk but CLI looks up wrong inode #704, list_projects (via build_project_json_entry) and resolve_store_fallback_scan key on the db's INTERNAL project name via db_internal_project_name, which requires the projects table to contain exactly one row: n == 1 at src/mcp/mcp.c#L1338.

Once the shadow row lands, n == 2db_internal_project_name returns false → the db is treated as "ghost / unreadable" and skipped from the listing, and the fallback-scan resolve path fails as well.

Reproduction

# index any repo that produces >= 1 parse failure (or add the row manually):
sqlite3 ~/.cache/codebase-memory-mcp/<project>.db \
  "INSERT INTO projects(name, indexed_at, root_path) VALUES ('<project>::missed','2026-01-01T00:00:00Z','');"
codebase-memory-mcp cli list_projects
# → {"projects":[], "hint":"No projects indexed. ..."}  — while the db has 70k nodes

Deleting the ::missed row makes the project reappear immediately.

Expected behavior

Internal shadow projects (*::missed) are ignored when deriving the db's internal name; the primary project stays listed and resolvable.

Proposed fix

In db_internal_project_name, filter out rows whose name contains :: and require exactly one primary row, instead of n == 1 over all rows. I have a patch with a reproduce-first regression test (modeled on the #704 test fixture) and will open a PR referencing this issue shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    parsing/qualityGraph extraction bugs, false positives, missing edgesux/behaviorDisplay bugs, docs, adoption UX

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions