Skip to content

Node ID collisions when multiple files share the same stem (e.g. Program.cs) #438

Open

Description

@V0v1kkk

Problem

_make_id(stem, name) uses only the file stem to generate node IDs. When a project has multiple files with the same name in different directories (e.g. src/App1/Program.cs and src/App2/Program.cs), their nodes collide — methods from both files merge into a single node, producing an incorrect graph.

This is common in .NET solutions where each project has its own Program.cs, Startup.cs, AssemblyInfo.cs, etc.

Proposed Fix

Add a post-extraction pass that detects colliding node IDs (multiple nodes from different source_file paths sharing the same ID) and disambiguates them by prepending the parent directory name.

For example:

  • program_program → app1_program_program and app2_program_program

Impact

Tested on a .NET solution with 2 Program.cs files — nodes are now correctly separated.

I have a PR ready.

Activity

  1. GustavoStingelin commented on Apr 22, 2026

    @GustavoStingelin

    same problem here, this is very common in golang side tho

  2. maticijus commented on May 7, 2026

    @maticijus

    Confirming this issue is language-agnostic — Python repro on graphifyy v0.5.0:

    A trading-system codebase has 14 separate cli.py files, one per skill (insider-flow/cli.py, npt-delta/cli.py, sector-flow/cli.py, x-cashtag/cli.py, data-store/cli.py, signal-enrichment/cli.py, risk-manager/cli.py, confirmation-signals/cli.py, …).

    All 14 main() functions collapse to a single node ID cli_main (format {stem}_{symbol}). Result:

    • That phantom node ranks Wroked out examples missing graph.html #3 god node, degree=115
    • 85 of 115 neighbors land in one community (because that's where the collision-edges glue everything to)
    • 30 cross-community edges spread across 11 communities — looks like a major architectural bridge but is actually 14 independent CLI scripts each touching their own local helpers

    Same root cause as the Program.cs case in this issue. Worth noting the fix should cover the entire common-filename family in idiomatic Python:

    cli.py, __init__.py, __main__.py, types.py, utils.py, helpers.py, conftest.py, tests.py, models.py, schemas.py

    …and JavaScript:

    index.js/.ts, App.jsx, types.ts, utils.ts

    Proposed fix in the issue (post-extraction collision-detection pass that disambiguates by source_file) would resolve all of these.

  3. V0v1kkk commented on May 8, 2026

    @V0v1kkk
    Author

    @maticijus thanks for the detailed Python repro — 14 cli.py files collapsing into a single god node is a great example of this issue in the wild.

    The fix in PR #441 handles all of these cases. It detects colliding IDs (from any language — C#, Python, JS, Go, etc.) and disambiguates them using progressively deeper path components from the source file. So insider-flow/cli.py → insider_flow_cli_main, npt-delta/cli.py → npt_delta_cli_main, etc.

    Latest push also fixes an edge case where the renamed ID could shadow an existing node from a different group (reported by @Qodo-Free-For-OSS on the PR).

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions