Summary
Function-valued consts are indexed at module scope but not inside a function
body. In a React codebase that means most event handlers are absent from the
graph, and callers / callees / impact answer Symbol not found for them
— which reads identically to "this symbol has no callers".
The boundary is scope, not syntax: a top-level const fn = () => {} indexes
fine, and the same declaration inside a component does not. useCallback is
not involved — a bare arrow inside the component is missing too.
Reproduction
Two files, no dependencies, codegraph init:
src/widget.jsx
import { useCallback } from "react";
export function formatLabel(value) { // 1. top-level declaration
return String(value).trim();
}
export const parseLabel = (raw) => raw.split(":")[1]; // 2. top-level arrow const
export class Formatter { // 3. class + method
render(value) { return formatLabel(value); }
}
export default function Widget({ items, onPick }) {
const handleSelect = useCallback((item) => { // 4. const in a component, via hook
onPick(formatLabel(item), parseLabel(item));
}, [onPick]);
const handleClear = () => { // 5. plain const in a component
onPick(null, null);
};
return items.map((i) => (
<button key={i} onClick={() => handleSelect(i)} onDoubleClick={handleClear}>
{formatLabel(i)}
</button>
));
}
src/page.jsx
import Widget, { formatLabel, parseLabel } from "./widget";
export default function Page() {
const label = formatLabel("a:b");
const parsed = parseLabel("a:b");
return <Widget items={[label, parsed]} onPick={() => {}} />;
}
Result
codegraph init reports 10 nodes. Every node in the index:
file page.jsx src/page.jsx:1
import ./widget src/page.jsx:1
function Page src/page.jsx:3
file widget.jsx src/widget.jsx:1
import react src/widget.jsx:1
function formatLabel src/widget.jsx:4
function parseLabel src/widget.jsx:9
class Formatter src/widget.jsx:12
method render src/widget.jsx:13
function Widget src/widget.jsx:18
handleSelect (line 19) and handleClear (line 23) are absent.
codegraph callers formatLabel → 4 callers
codegraph callers parseLabel → 3 callers
codegraph callers Widget → 1 caller
codegraph callers handleSelect → Symbol "handleSelect" not found
codegraph callers handleClear → Symbol "handleClear" not found
Note line 9: parseLabel is an arrow function and indexes correctly. Only the
two declared inside Widget are missing.
Expected
handleSelect and handleClear are declared functions with a name, a body and
call sites, and should appear as nodes the same way parseLabel does.
Why it matters
This is the dominant shape for handlers in React, so on a real front end a
large share of the functions an agent needs are invisible. The failure is also
silent in the worst direction: Symbol not found is indistinguishable from
"nothing calls this", so an agent asked to update every call site of a handler
gets an empty answer and concludes there are none. Grep finds them, which is
the fallback CodeGraph is meant to replace.
The same gap presumably affects const x = function () {}, object-literal
methods, and IIFE-scoped helpers in plain JS/TS, though I only measured the
React case.
Environment
- codegraph 1.6.0 (npm
@colbymchenry/codegraph)
- node v26.7.0
- macOS 26.4.1, arm64
Possibly related
#1656 (route callers/callees/impact through one symbol resolver) looks adjacent
— though this appears to be extraction rather than resolution, since the nodes
never reach the database at all.
Summary
Function-valued
consts are indexed at module scope but not inside a functionbody. In a React codebase that means most event handlers are absent from the
graph, and
callers/callees/impactanswerSymbol not foundfor them— which reads identically to "this symbol has no callers".
The boundary is scope, not syntax: a top-level
const fn = () => {}indexesfine, and the same declaration inside a component does not.
useCallbackisnot involved — a bare arrow inside the component is missing too.
Reproduction
Two files, no dependencies,
codegraph init:src/widget.jsxsrc/page.jsxResult
codegraph initreports 10 nodes. Every node in the index:handleSelect(line 19) andhandleClear(line 23) are absent.Note line 9:
parseLabelis an arrow function and indexes correctly. Only thetwo declared inside
Widgetare missing.Expected
handleSelectandhandleClearare declared functions with a name, a body andcall sites, and should appear as nodes the same way
parseLabeldoes.Why it matters
This is the dominant shape for handlers in React, so on a real front end a
large share of the functions an agent needs are invisible. The failure is also
silent in the worst direction:
Symbol not foundis indistinguishable from"nothing calls this", so an agent asked to update every call site of a handler
gets an empty answer and concludes there are none. Grep finds them, which is
the fallback CodeGraph is meant to replace.
The same gap presumably affects
const x = function () {}, object-literalmethods, and IIFE-scoped helpers in plain JS/TS, though I only measured the
React case.
Environment
@colbymchenry/codegraph)Possibly related
#1656 (route callers/callees/impact through one symbol resolver) looks adjacent
— though this appears to be extraction rather than resolution, since the nodes
never reach the database at all.