Version
0.11.0 (release). Also reproduced on main @ 96c3f41 built from source.
Platform
Linux (x64)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
Since Go 1.22, http.ServeMux patterns may include an HTTP method and/or host:
mux.HandleFunc("POST /v1/payments", h), mux.HandleFunc("GET /v1/payments/{id}", h),
mux.HandleFunc("GET api.example.com/v1/x", h)
(https://pkg.go.dev/net/http#hdr-Patterns-ServeMux).
Registrations written this way produce no Route nodes and no HANDLES edges. The
same file using legacy patterns ("/v1/payments") produces 2 Routes. As a result, any
Go service using the 1.22+ syntax is invisible to cross-repo HTTP matching.
Expected: Route POST /v1/payments and Route GET /v1/payments/{id}, each with a HANDLES
edge to its handler. That is, the method is taken from the pattern instead of ANY, and a
host, if present, is dropped or recorded as a property.
Reproduction
- Code (
go.mod: module example.com/srv, go 1.22):
package main
import "net/http"
func createPayment(w http.ResponseWriter, r *http.Request) {}
func getPayment(w http.ResponseWriter, r *http.Request) {}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("POST /v1/payments", createPayment)
mux.HandleFunc("GET /v1/payments/{id}", getPayment)
_ = http.ListenAndServe(":8080", mux)
}
- Commands:
codebase-memory-mcp cli index_repository '{"repo_path":"/path/to/repo"}'
codebase-memory-mcp cli get_graph_schema '{"project":"<project>"}'
- Output: no
Route label and no HANDLES edges. With "/v1/payments" and
"/v1/payments/{id}" instead, the same commands report Route 2 and HANDLES 2.
A script that runs this and the control is attached as repro.sh, section "Issue 1".
Suspected cause (from reading the source at 96c3f41; may be incomplete)
Every route-registration path requires the first string argument to start with /:
src/pipeline/pass_parallel.c:2058 is_route_path_shaped() (val[0] == '/')
src/pipeline/pass_calls.c:593 and :768
internal/cbm/extract_calls.c:3962 (handler arg extraction is gated on '/')
"POST /v1/payments" therefore never qualifies. Parsing an optional
METHOD SP prefix and an optional host before the first / would cover the
documented grammar.
Full self-contained script (creates throwaway repos in a temp dir, isolated cache): see attached repro.sh.txt, section "Issue N". Run with bash repro.sh.txt [path/to/codebase-memory-mcp].
repro.sh.txt
Logs
"== Issue 1: Go 1.22 ServeMux method patterns produce no Route"
for v in modern legacy; do
if [ $v = modern ]; then P1='POST /v1/payments'; P2='GET /v1/payments/{id}'; else P1='/v1/payments'; P2='/v1/payments/{id}'; fi
repo "i1-$v" go.mod <<<'module example.com/srv
go 1.22'
repo "i1-$v" main.go <<GO
package main
import "net/http"
func createPayment(w http.ResponseWriter, r *http.Request) {}
func getPayment(w http.ResponseWriter, r *http.Request) {}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("$P1", createPayment)
mux.HandleFunc("$P2", getPayment)
_ = http.ListenAndServe(":8080", mux)
}
GO
commit "i1-$v"; index "i1-$v"
done
check "Route nodes, Go 1.22 patterns (\"POST /v1/payments\")" "$(count i1-modern Route)" 2
check "Route nodes, legacy patterns (\"/v1/payments\") " "$(count i1-legacy Route)" 2
Diagnostics trajectory (memory / performance / leak issues)
Project scale (if relevant)
No response
Confirmations
Version
0.11.0 (release). Also reproduced on main @ 96c3f41 built from source.
Platform
Linux (x64)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
Since Go 1.22,
http.ServeMuxpatterns may include an HTTP method and/or host:mux.HandleFunc("POST /v1/payments", h),mux.HandleFunc("GET /v1/payments/{id}", h),mux.HandleFunc("GET api.example.com/v1/x", h)(https://pkg.go.dev/net/http#hdr-Patterns-ServeMux).
Registrations written this way produce no Route nodes and no HANDLES edges. The
same file using legacy patterns (
"/v1/payments") produces 2 Routes. As a result, anyGo service using the 1.22+ syntax is invisible to cross-repo HTTP matching.
Expected: Route
POST /v1/paymentsand RouteGET /v1/payments/{id}, each with a HANDLESedge to its handler. That is, the method is taken from the pattern instead of
ANY, and ahost, if present, is dropped or recorded as a property.
Reproduction
go.mod:module example.com/srv,go 1.22):Routelabel and noHANDLESedges. With"/v1/payments"and"/v1/payments/{id}"instead, the same commands reportRoute 2andHANDLES 2.A script that runs this and the control is attached as repro.sh, section "Issue 1".
Suspected cause (from reading the source at 96c3f41; may be incomplete)
Every route-registration path requires the first string argument to start with
/:src/pipeline/pass_parallel.c:2058is_route_path_shaped()(val[0] == '/')src/pipeline/pass_calls.c:593and:768internal/cbm/extract_calls.c:3962(handler arg extraction is gated on'/')"POST /v1/payments"therefore never qualifies. Parsing an optionalMETHOD SPprefix and an optional host before the first/would cover thedocumented grammar.
Full self-contained script (creates throwaway repos in a temp dir, isolated cache): see attached repro.sh.txt, section "Issue N". Run with bash repro.sh.txt [path/to/codebase-memory-mcp].
repro.sh.txt
Logs
Diagnostics trajectory (memory / performance / leak issues)
Project scale (if relevant)
No response
Confirmations