Repository navigation
Description
Environment: v0.10.2, Windows 11, daemon mode. Reproduced on a 2-file synthetic repo and on a real Python+TypeScript monorepo (~41.8k nodes / ~198.8k edges, --mode full).
Symptom
A Python from unittest.mock import patch binds to a TypeScript function named patch, in a different language, in a different top-level package. Every with patch(...) in the repo is then recorded as a CALLS edge into that TSX function.
In my real repo this produced a 4-line React helper with 498 inbound callers, all of them backend Python tests:
// frontend/src/components/gates/reportgate/ReportGatePanel.tsx:151-154
function patch(changes: Partial<ReportGateState>) {
if (!state) return
applyEdit({ ...state, ...changes })
}Minimal reproducer
Two files, no dependencies (24 nodes / 28 edges):
frontend/Panel.tsx
export function Panel() {
function patch(changes: Partial<State>) {
applyEdit({ ...changes })
}
return patch
}backend/test_thing.py
from unittest.mock import patch
def test_one():
with patch("os.getcwd", return_value="/tmp"):
pass
def test_two():
with patch("os.getcwd", return_value="/tmp"):
passcodebase-memory-mcp cli index_repository --repo-path <repo> --mode fast
codebase-memory-mcp cli trace_path --project <p> --function-name patch \
--direction inbound --include-evidence true --include-tests true
Result:
function: patch
direction: inbound
callers_total: 2
callers: 2 (rows: name hop strategy confidence)
test_one 1 heuristic 0.75
test_two 1 heuristic 0.75
Root cause: the IMPORTS edge is already wrong, and it is not an ambiguity failure
The bad binding happens at the import, not at the call site:
MATCH (a)-[r:IMPORTS]->(b) RETURN a.name, a.file_path, b.qualified_name, r.local_name
test_thing.py | backend/test_thing.py | <proj>.frontend.Panel.patch | patch
from unittest.mock import patch resolved to a project-local TSX node. The CALLS edges then faithfully follow that import binding.
The edge metadata is the important part:
MATCH (a)-[r:CALLS]->(b) WHERE b.name = 'patch'
RETURN a.file_path, b.file_path, r.strategy, r.confidence, r.candidates
backend/test_thing.py | frontend/Panel.tsx | unique_name | 0.75 | 1
strategy=unique_name, candidates=1. The resolver is not choosing badly among several candidates — it sees exactly one node named patch in the whole graph and treats that as proof, with no language check and no check that the import specifier (unittest.mock) is external.
This means #1555's proposed fix does not cover this case. That issue asks for better disambiguation when candidates > 1; here candidates == 1, so the ambiguity path is never entered. The two issues are complementary: #1555 is same-language ambiguity, this is a cross-language false positive on a unique name.
Why this is worse than a bad trace hop
The wrong edges silently contaminate the aggregate analyses that agents treat as ground truth:
get_architecturehotspots. The 4-line React helper is reported as the FastAPI empty-path routes not captured #8 hotspot in the repo (fan_in 498), ahead of real infrastructure. Hotspots do not surfaceconfidence, so nothing signals that the entry is fabricated.- Louvain clustering. The node becomes an artificial hub: ~498 backend test functions get pulled into one cluster together with
frontendandfrontend-mockups, reported at cohesion 0.78. The cluster looks like a genuine architectural seam spanning four packages. It is an artifact. - Dead-code / impact analysis. Anything keying off fan-in inherits the error.
A second instance in the same repo: RuntimeFlagResolver.get reports fan_in 611, whose "callers" are module-level __file__ statements — though that one is at least honestly scored (confidence 0.06, vs 0.95 for the patch edges in the real repo).
Python is especially exposed because stdlib names (patch, get, run, main, setup) collide constantly with short method names in other languages. builtins.* names appear to be handled by a synthetic-node path already; unittest.mock.patch is not a builtin and falls through it.
Suggested fixes
In rough order of value:
- Never resolve an import or call across a language boundary. A Python
importshould not bind to a.tsxnode under any strategy. This alone eliminates the whole class. - Treat a resolved import specifier as external when it does not correspond to a project-local module.
unittest.mockis not a path in the repo; the specifier is already parsed, since theIMPORTSedge carrieslocal_name. Binding to a synthetic external node (asbuiltins.*seems to do) would be consistent with existing behavior. - Do not let
strategy=unique_nameimply high confidence. Uniqueness within the graph is not evidence of a call relationship when the only candidate is in another language/package. Consider capping confidence for cross-packageunique_namehits. - Propagate confidence into aggregates.
get_architecturehotspots/clusters could exclude or flag edges below a confidence threshold, or expose the weakest strategy contributing to a hotspot. Related: trace_path format=json drops include_evidence strategy and confidence #1542 (strategy/confidence dropped informat=json).
Happy to test a patch against the real repo — the misresolution is deterministic there and easy to re-measure via trace_path --include-evidence.
Activity
DeusData commentedon Aug 12, 2026
Thank you @SQLBImhugh. Confirmed on current
main: the registry'sby_nameindex has no language dimension, and when exactly one simple-name candidate exists,resolve_name_lookup()returns it with strategyunique_nameregardless of the caller and candidate languages. Import reachability only lowers confidence; it does not reject the cross-language target.This is the same resolver class behind #725 and overlaps the receiver-ambiguity case in #1555, but your deterministic Python-to-TypeScript case is a useful root-level fixture rather than a duplicate. Routed priority/high under #594.
fix(registry): drop suffix_match CALLS across language boundaries
rudi193-cmd commentedon Aug 18, 2026
Claiming this as the #1647 follow-on: same language-family guard, now for
unique_name(candidates == 1).#1647 dropped
suffix_matchCALLS across language boundaries and left this case alone on purpose. The helper still returns false forunique_name; the two-file Pythonfrom unittest.mock import patch/ TSXfunction patchfixture is the red test.Plan, one PR:
cbm_suppress_cross_language_suffix_matchsounique_nameis dropped under the same rules (JS/TS/TSX one family; unknown-extension targets kept;same_module/import_map/lsp_*kept).test_one/test_twomust not CALL the TSXpatch.unittest.mockas an external specifier (Python stdlib import binds to a same-named TypeScript function (cross-language, strategy=unique_name) — poisons hotspots and Louvain clusters #1572 suggestion 2), Call resolution picks the wrong target (or none) for common method names in a Kotlin monorepo #1555 receiver disambiguation, or fix(pipeline): refuse same_module for import-bound or builtin JS/TS receivers #1128.Will open after this comment unless someone is already on it.
fix(registry): drop unique_name CALLS across language boundaries
fix(pipeline): apply DeusData#1572 CALLS guard on LSP lsp_direct homo…
fix(registry): drop unique_name CALLS across language boundaries
fix(pipeline): apply DeusData#1572 CALLS guard on LSP lsp_direct homo…
fix(pipeline): drop cross-language LSP homonym CALLS (DeusData#1572)
style(pipeline): clang-format lsp builtin helper (DeusData#1572)
fix(pipeline): suppress import_map cross-lang CALLS homonyms (DeusDat…
style(pipeline): clang-format calls_edge homonym check (DeusData#1572)
style(pipeline): clang-format calls_edge homonym check (DeusData#1572)
style(pipeline): wrap homonym line for clang-format 100-col (DeusData…
fix(registry): drop unique_name CALLS across language boundaries
fix(registry): widen CALLS families for CUDA, ObjC, HTML (DeusData#1702)
fix(pipeline): apply DeusData#1572 CALLS guard on LSP lsp_direct homo…
fix(pipeline): drop cross-language LSP homonym CALLS (DeusData#1572)
style(pipeline): clang-format lsp builtin helper (DeusData#1572)
fix(pipeline): suppress import_map cross-lang CALLS homonyms (DeusDat…
style(pipeline): clang-format calls_edge homonym check (DeusData#1572)
style(pipeline): wrap homonym line for clang-format 100-col (DeusData…
test(pipeline): keep DeusData#1572 integration test on external-speci…
DeusData commentedon Oct 19, 2026
Thank you for the focused unique_name follow-on plan and for keeping external-specifier handling and receiver disambiguation separate. I have no new review or fix outcome to report here. The two-file Python/TSX example remains the useful check for this specific false edge.
DeusData commentedon Oct 25, 2026
Thank you for the focused unique-name follow-on and Python/TSX fixture. Review of this false cross-language edge remains outstanding, separate from external-module handling. Sorry for the delay; this is waiting on maintainer follow-up, and I’ll follow up soon.