Skip to content

Call resolution picks the wrong target (or none) for common method names in a Kotlin monorepo #1555

Closed

Description

@PsyTech-Rob

Environment: v0.10.2, Windows 11, daemon mode, --mode full index. Kotlin (Spring) + TypeScript monorepo, ~20.6k nodes / ~101.7k edges.

Symptom

trace_path(mode=calls) resolves call hops by name, and for method names shared by many symbols it either picks a wrong target or silently returns nothing:

  1. Wrong target across modules. A use-case method calls repository.inserir(...) where the receiver is the domain port CompromissoRepository (constructor-injected). The trace lists the callee as JooqFeriadoRepository.inserir — an implementation of a different port in a different bounded context that happens to share the method name. The correct implementation is identifiable in the same graph via the OVERRIDE edge (JooqCompromissoRepository.inserir → CompromissoRepository.inserir), so the information needed to disambiguate exists.

  2. Missing callers. The same use-case method (executar, also a very common name in this codebase) shows callers_total: 0, although a controller in the same module calls it directly one file away. Unique names resolve perfectly — an extension function with 4 call sites returned exactly those 4 callers.

Suggestion

When candidates > 1 for a hop:

  • prefer the declared receiver/parameter type (present in source and, for implementations, derivable from OVERRIDE/INHERITS), and/or
  • surface the ambiguity in trace_path output — the CALLS edge already stores candidates and confidence, but the trace renders an ambiguous hop with the same look as an exact one (related: trace_path format=json drops include_evidence strategy and confidence #1542, which asks for strategy/confidence in format=json).

Agents treat a trace as evidence; a wrong hop that looks identical to a right hop is worse than no hop.

Activity

  1. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Aug 12, 2026
  2. DeusData commented on Aug 12, 2026

    @DeusData
    Owner

    Thank you @PsyTech-Rob. The current resolver confirms the risk: after stronger lookups fail, same-name candidates are selected through import reachability and import-distance scoring. Receiver/parameter type and existing OVERRIDE relationships are not consistently part of that final candidate decision, so a plausible but wrong method can receive the CALLS edge.

    The evidence-output gap is fixed on main by #1542, but that does not fix target selection. This remains a priority/high resolution bug under #594 and is cross-linked with the cross-language unique_name case in #1572 and the resulting hotspot inflation in #725.

  3. added a commit that references this issue on Oct 18, 2026
  4. DeusData commented on Oct 18, 2026

    @DeusData
    Owner

    Fixed on main by #2682 (merge bddacfe): Kotlin calls through typed class properties now resolve through the Kotlin LSP. On 14 open-source Kotlin repositories that adds 2,702 correct CALLS edges and removes 2,420 wrong guesses, with the same result on both the parallel and the sequential resolver. Thank you very much for reporting this, it was a real gap and the report made it easy to reproduce.

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.windowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions