Go: factory calls and GORM-style chains resolve to unrelated symbols
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 22/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- go, typescript
- Domain
- tooling
Research direction
Start by running the synthetic Go reproduction in the issue against a fresh index, then inspect codegraph callees Find output. The bare Query() call is resolved through the Go model-name heuristic in src/resolution/frameworks/go.ts, and the chained Where/First calls go through src/resolution/name-matcher.ts. Done means Find no longer gets edges to CardDo, and the Query() call points to mysql/conn.go.
Written by the indexing model from the issue text.
Description
On CodeGraph 1.6.2, a Go factory → field → fluent-method chain can produce incorrect graph edges after a fresh index. A same-package factory call resolves to an unrelated struct, and chained methods resolve to another query type's same-named methods.
The reproduction below is entirely synthetic. It models the shape of GORM-generated query code and requires no GORM dependency, database, credentials, or application code.
Environment: CodeGraph 1.6.2, release commit 6560052a6f856855d3f71eee838fd66ccfa4285d; Linux x86_64; bundled Node.js 24.16.0.
Run this with an unmodified CodeGraph 1.6.2 installation:
repro_dir="$(mktemp -d)"
mkdir -p "$repro_dir/query" "$repro_dir/mysql"
cat > "$repro_dir/go.mod" <<'EOF'
module example.com/app
go 1.22
EOF
cat > "$repro_dir/query/query.go" <<'EOF'
package query
type Query struct { Session Session }
EOF
cat > "$repro_dir/query/card.go" <<'EOF'
package query
type CardDo struct{}
func (c CardDo) Where(value int) CardDo { return c }
func (c CardDo) First() int { return 1 }
EOF
cat > "$repro_dir/query/session.go" <<'EOF'
package query
type Session struct{}
type SessionDo struct{}
func (s Session) WithContext(ctx int) SessionDo { return SessionDo{} }
func (s SessionDo) Where(value int) SessionDo { return s }
func (s SessionDo) First() int { return 2 }
EOF
cat > "$repro_dir/mysql/conn.go" <<'EOF'
package mysql
import "example.com/app/query"
func Query() *query.Query { return &query.Query{} }
EOF
cat > "$repro_dir/mysql/session.go" <<'EOF'
package mysql
func Find() int {
model := Query().Session
return model.WithContext(0).
Where(1).
First()
}
EOF
codegraph init --yes "$repro_dir"
codegraph callees Find --file mysql/session.go --json --path "$repro_dir"
The relevant outgoing edges for Find, normalized from the resulting graph, are:
calls CardDo::First query/card.go
calls CardDo::Where query/card.go
instantiates Query query/query.go
calls Session::WithContext query/session.go
Find calls the function mysql.Query() from mysql/conn.go, then operates on Query().Session. It never uses CardDo. The factory call should point to mysql/conn.go; Where and First should point to SessionDo if their receiver can be resolved. When the receiver cannot be established, leaving those method references unresolved is preferable to creating edges to CardDo.
These false edges affect callers, callees, impact analysis, and the relationships shown by codegraph_explore.
I traced the reproduction to two resolution paths in v1.6.2:
- The Go model-name heuristic in
src/resolution/frameworks/go.tscan nominate an out-of-package struct for a bare call such asQuery(). That heuristic can win against the real same-package function, after which the edge becomesinstantiates. The Service/Store/Repository naming patterns have the same failure mode. - Later links in the Go fluent chain reach name matching without their receiver type.
src/resolution/name-matcher.tsthen picks one of several same-named methods using proximity, producing the unrelatedCardDoedges.
A conservative local candidate fix addresses these paths:
- Restrict the type candidates offered by the Go framework heuristic for bare calls to the caller's package, preserving legitimate same-package type conversions.
- Require receiver evidence from the current call expression before treating a bare extracted name as a collapsed fluent call, and decline ambiguous method-name matches. The check must handle long multiline arguments, comments, and Go raw strings without borrowing a receiver from a later expression.
Validation of the local candidate: 438 tests passed across 11 related suites, including 13 regression cases. The dedicated cases also passed with both the native kernel and WASM fallback. They cover the factory/type collision, single-line and long multiline chains, known typed receivers, same-package conversions (including parentheses, pointers, and comments), later same-name expressions, and raw-string arguments. The candidate removes the false method edges and restores the factory edge; it does not implement complete GORM receiver-type inference.
Related reports: #1276 and #750. This reproduction covers the factory → struct field → fluent chain shape on v1.6.2.
- Dominant language
- C
- Stars
- 73.2k
- Forks
- 4.7k
- Avg merge
- 2h 16m
- Merged PRs (30d)
- 423
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from colbymchenry/codegraph
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
colbymchenry/codegraph#2634 ·
Maintainers usually reply within 1 day
-
Windows: bundled Node v24.16.0 can abort at exit (nodejs/node#56645); please bundle Node >= 24.20.0Possibly taken @Ancienttwo claimed this 3 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
colbymchenry/codegraph#2617 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 Under an hour Newbie friendliness 72/100
colbymchenry/codegraph#2482 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
colbymchenry/codegraph#1900 · 2 comments · 5 reactions ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
colbymchenry/codegraph#1700 ·
Maintainers usually reply within 1 day
All issues in colbymchenry/codegraph
Similar issues
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
EchoTools/nevr-runtime#698 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
FujiNetWIFI/fujinet-firmware#2079 ·
Maintainers usually reply within 1 day
-
bug Official Image release/25.12 Supported Device target/kirkwood
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
area/archive bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
DarkFlippers/qUnleashed#374 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 84/100
VirusTotal/yara#2255 ·