Skip to content

Java: interface methods emitted twice — as both Method and Function nodes (472 spurious Function nodes) #1234

Closed

Description

@masesas

Environment

  • codebase-memory-mcp 0.9.0 (macOS arm64, Darwin 25.0.0)
  • Project: Java 21 / Spring Boot 3 monorepo, ~1,358 Java files, indexed in full mode (20,530 nodes / 70,485 edges)

Summary

Methods declared on Java interfaces are emitted as two nodes: a Method (correct, with parent_class) and a duplicate Function node at the same file/line. Java has no free-standing functions, so any Function node in a .java file is spurious. Our graph has 472 Function nodes pointing into .java files.

Repro

Source (MarketplaceReservationService.java, an interface):

ReservationResponseDTO createReservation(Authentication authentication, ReservationRequestDTO request);

Cypher:

MATCH (m) WHERE m.name = 'createReservation' RETURN m.qualified_name, labels(m)

Result contains both:

...reservation.service.MarketplaceReservationService.createReservation  ["Method"]
...reservation.service.createReservation                                ["Function"]   <- duplicate, same file/line

Aggregate check:

MATCH (f:Function) WHERE f.file_path ENDS WITH '.java' RETURN count(f)  // 472

Impact

  • Search results show doubled entries for interface methods.
  • Node/label counts and any per-label analytics are skewed.
  • Structural boosting in BM25 (Functions +10) double-boosts these phantoms.

Notes

Looks like the interface-body visitor emits the method both under the parent type and at file scope. Happy to test a fix.

Activity

  1. added
    bugSomething isn't working
    parsing/qualityGraph extraction bugs, false positives, missing edges
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    and removed
    cypherCypher query language parser/executor bugs
    on Jul 24, 2026
  2. added this to the 0.9.1-rc milestone on Jul 24, 2026
  3. DeusData commented on Jul 24, 2026

    @DeusData
    Owner

    Confirmed as an extraction invariant: Java interface members are methods, and the same source span must not also produce a top-level Function node. The RED should assert one Method node for the interface declaration and zero Function nodes at the same file and line before testing aggregate counts. High priority for 0.9.1-rc under #592.

  4. harshitaajoshi commented on Jul 29, 2026

    @harshitaajoshi
    Contributor

    I would like to work on this. I traced the root cause to push_class_body_children() in internal/cbm/extract_defs.c: it does not recognize interface_body as a class body container (unlike find_class_body(), which already does), so the fallback path pushes method_declaration children back onto the walk stack and extract_func_def() mints a duplicate Function node.

    I'll add interface_body (and enum_body for the same class of bug) to the body container check, with a reproduce-first regression test that asserts one Method node and zero same-line Function nodes for interface methods.

  5. DeusData commented on Aug 4, 2026

    @DeusData
    Owner

    Fixed on main: 87a0e3f made class-body routing language-agnostic, so Java interface/enum methods are extracted once as Method nodes — the duplicate top-level Function nodes (the 472 spurious nodes you counted) are gone. We verified against current main with dedicated regression tests, landing via #1433 (distilled from @harshitaajoshi's #1327): they pass on main and reproduce your exact symptom (duplicate Function nodes) the moment the routing regresses.

    Thank you for the precise report — the node counts and the interface/enum split made this easy to pin down and to bind in the suite.

  6. added a commit that references this issue on Aug 4, 2026
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.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions