Skip to content

Angular component sibling files (ts/html/scss) merged into one File node; search_code silently incomplete #769

Closed

Description

@artaommahe

Version

codebase-memory-mcp 0.8.1

Platform

macOS (Apple Silicon)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

When indexing an Angular project, the indexer creates one File node per component and folds the component's sibling files (foo.component.ts / .html / .scss) into it. Only one sibling's path survives as file_path, and which one wins is inconsistent (sometimes .ts, sometimes .html, sometimes .scss). The other siblings disappear from the file inventory entirely.

Consequences:

  1. search_code silently returns incomplete results — it only greps files that have their own File node, so matches inside merged-away templates are never found, with no truncation warning. On a real ~10k-file Angular monorepo, a sweep for a CSS class found 95 of 137 grep matches (~70%); ~630 of 1,041 .html templates had no File node.
  2. Wrong-facet paths in results — a component can be represented by its .scss path, so query results/callers point at a stylesheet.
  3. extension / file_path mismatch — on the large repo, nodes appear with extension: '.html' but a file_path ending in .ts or .scss.

Expected: one File node per file on disk (or, if component+template merging is intentional for call-graph purposes, the merged siblings should still be present in the file inventory that search_code and file-level queries operate on — call extraction itself handles the merge fine, see below).

Reproduction

Public minimal repro (13 source files, dummy code): https://github.com/artaommahe/codebase-memory-mcp-angular-repro @ bbc0779

It contains three tiny components engineered to trigger each merge outcome (add-absence: ts+html; checkbox: ts+html+spec+stories; badge: ts+html+scss), a standalone help.html control with no component sibling, and a FeatureService.isEnabled() called from two components. All four .html files contain the literal marker repro-marker.

  1. index_repository {"repo_path":"<repro>","mode":"full"} → 34 nodes / 54 edges

  2. query_graph {"query":"MATCH (f:File) RETURN f.file_path, f.extension ORDER BY f.file_path"}

    Result — 7 File nodes instead of 13:

    src/app/add-absence/add-absence.component.ts   .ts     <- add-absence.component.html GONE
    src/app/badge/badge.component.scss             .scss   <- badge .ts AND .html GONE
    src/app/checkbox/checkbox.component.html       .html   <- checkbox.component.ts GONE
    src/app/checkbox/checkbox.component.spec.ts    .ts
    src/app/checkbox/checkbox.component.stories.ts .ts
    src/app/feature.service.ts                     .ts
    src/standalone/help.html                       .html
    
  3. search_code {"pattern":"repro-marker","mode":"files"}

    Result — 2 of 4 files (checkbox.component.html, help.html); missing add-absence.component.html and badge.component.html, both found by plain grep -rl repro-marker src/.

  4. Control checks: trace_path {"function_name":"isEnabled","direction":"inbound"} correctly returns both callers (AddAbsenceComponent.save, BadgeComponent.isHighlighted) — call extraction is unaffected; the standalone help.html (no component sibling) is indexed correctly.

Full expected-vs-actual write-up in the repro repo's README.

Project scale (if relevant)

Repro: 34 nodes / 54 edges / 13 files. Real-world Angular monorepo where this was found: 60,541 nodes / 124,930 edges / 10,330 files.

Confirmations

Activity

  1. artaommahe commented on Jul 2, 2026

    @artaommahe
    Author

    Follow-up on consequence 3 (extension / file_path mismatch) — it now reproduces in the repro repo too, and it turns out to require git history:

    • At the initial commit (bbc0779, single commit), extensions are consistent with the surviving path (add-absence.component.ts → .ts, badge.component.scss → .scss).
    • After adding commits that touch the merged siblings separately (10f18b4..5d07f94: one edits the .html, one the .scss, one the .ts) and re-running index_repository (mode full), the merged nodes' extension is corrupted:
    src/app/add-absence/add-absence.component.ts   ""      <- was ".ts" without history
    src/app/badge/badge.component.scss             ""      <- was ".scss"
    src/app/checkbox/checkbox.component.html       .html   <- unaffected (template path won the merge)
    

    Stable across repeated re-indexes. Only merged component nodes where a non-template sibling won the merge are affected. On the large real-world repo the same class of nodes instead shows extension: '.html' with a .ts/.scss file_path — so the value is order/environment-dependent: three different outcomes for the same logical situation.

    Repro repo updated with the exact steps: https://github.com/artaommahe/codebase-memory-mcp-angular-repro (README, "Follow-up" section, commit 5e39bf9).

    Posted by Claude Code on behalf of @artaommahe

  2. added
    bugSomething isn't working
    parsing/qualityGraph extraction bugs, false positives, missing edges
    ux/behaviorDisplay bugs, docs, adoption UX
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Jul 3, 2026
  3. DeusData commented on Jul 3, 2026

    @DeusData
    Owner

    Thanks for the Angular repro. Triage: high-priority parsing/search correctness under #592 and #396.

    File identity must remain one File node per actual source/template/style file; sibling Angular component files should not collapse into one graph node. The search_code impact makes this more than a cosmetic graph issue, so the regression should assert separate File nodes and complete text-search coverage for .ts, .html, and .scss siblings.

  4. added this to the 0.9.1-rc milestone on Jul 8, 2026
  5. DeusData commented on Jul 15, 2026

    @DeusData
    Owner

    This is the same root cause as #1077/#964: cbm_pipeline_fqn_compute stripped the file extension when computing File-node qualified names, so foo.component.ts, foo.component.html, and foo.component.scss all reduced to the stem foo.component and collided — only one File node survived per component.

    Fixed by PR #1108 (in CI now, shipping v0.9.1): File-node QNs preserve the full filename, so the three sibling files get distinct File nodes. Verified end-to-end on an @Component fixture — .ts, .html, .scss all present as separate File nodes. (Module/symbol QNs keep extension stripping, so cross-file resolution is unaffected.) Will auto-close when #1108 merges.

  6. artaommahe commented on Jul 30, 2026

    @artaommahe
    Author

    Confirming this looks fixed in 0.9.1-rc.1 (macOS arm64, standard variant), on the same ~11.8k-file Angular monorepo that produced the original numbers.

    The original report measured ~630 of 1,041 .html templates missing from the file inventory, and a search_code sweep finding 95 of 137 matches. After a full re-index on the RC, sibling files each have their own File node and the inventory matches the disk exactly:

    extension File nodes in graph files on disk (non-ignored)
    .html 1049 1049
    .scss 236 236
    MATCH (f:File) WHERE f.extension = '.html' RETURN count(f)   -> 1049
    MATCH (f:File) WHERE f.extension = '.scss' RETURN count(f)   -> 236
    

    No extension/file_path mismatches observed either. Thanks for sorting it — noting it here in case it's useful as a regression datapoint.


    Posted by Claude Code on behalf of @artaommahe

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

    bugSomething isn't workingparsing/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 UX

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions