Bug Description
When a function in file A calls a function in file B, the resulting CALLS edge is attached
to the Module node (file-level) rather than the specific Function node that contains
the call. This makes "find callers of X" queries return a file path instead of a function
name.
Steps to Reproduce
- Index a C project with cross-file function calls
- Run:
codebase-memory-mcp cli query_graph '{"project":"","query":
"MATCH (caller)-[:CALLS]->(callee) WHERE callee.name='''lp_uart_init'''
RETURN caller.name, caller.file_path"}'
caller.name returns the file path (e.g. components/.../lte_mgr.c) not a function
name
Root Cause (observed)
The CALLS edge has strategy=unique_name, confidence=0.75 and source_id="" (empty).
The source node's qualified_name is the Module node (...lte_mgr.lte_mgr), not a
Function.
The bt (body tokens) property on Function nodes does contain the callee symbol name,
confirming the indexer identified the call — but the edge is not linked to the specific
Function.
Expected Behavior
MATCH (caller:Function)-[:CALLS]->(callee:Function)
WHERE callee.name = 'lp_uart_init'
RETURN caller.name, caller.file_path, caller.start_line
Should return the specific caller function (e.g. lte_mgr_init at lte_mgr.c:414).
Impact
trace_call_path {"from_function": "X"} returns empty for cross-file calls
- "Find callers / impact analysis" queries (a core use case) silently return wrong granularity
Impact
trace_call_path {"from_function": "X"} returns empty for cross-file calls
- "Find callers / impact analysis" queries (a core use case) silently return wrong granularity
- Scored as
correct=1/2 in our A/B benchmark vs grep (8-question VCM C firmware suite)
Workaround
Two-step: get module name from CALLS edge → grep specific function in that file.
Or: get_code_snippet on candidate functions and check their bt field manually.
Environment
codebase-memory-mcp v0.7.0
- Project: ESP-IDF C firmware (C99, ~113 files, 428 functions, 343 CALLS edges)
- OS: Linux (Ubuntu 24.04)
Bug Description
When a function in file A calls a function in file B, the resulting
CALLSedge is attachedto the Module node (file-level) rather than the specific Function node that contains
the call. This makes "find callers of X" queries return a file path instead of a function
name.
Steps to Reproduce
codebase-memory-mcp cli query_graph '{"project":"","query":
"MATCH (caller)-[:CALLS]->(callee) WHERE callee.name='''lp_uart_init'''
RETURN caller.name, caller.file_path"}'
caller.namereturns the file path (e.g.components/.../lte_mgr.c) not a functionname
Root Cause (observed)
The CALLS edge has
strategy=unique_name, confidence=0.75andsource_id=""(empty).The source node's
qualified_nameis the Module node (...lte_mgr.lte_mgr), not aFunction.
The
bt(body tokens) property on Function nodes does contain the callee symbol name,confirming the indexer identified the call — but the edge is not linked to the specific
Function.
Expected Behavior
MATCH (caller:Function)-[:CALLS]->(callee:Function)
WHERE callee.name = 'lp_uart_init'
RETURN caller.name, caller.file_path, caller.start_line
Should return the specific caller function (e.g.
lte_mgr_initatlte_mgr.c:414).Impact
trace_call_path {"from_function": "X"}returns empty for cross-file callsImpact
trace_call_path {"from_function": "X"}returns empty for cross-file callscorrect=1/2in our A/B benchmark vs grep (8-question VCM C firmware suite)Workaround
Two-step: get module name from CALLS edge →
grepspecific function in that file.Or:
get_code_snippeton candidate functions and check theirbtfield manually.Environment
codebase-memory-mcpv0.7.0