From 1574b96f0f229653ce14fb7558a97a2d115271f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 05:11:10 +0000 Subject: [PATCH 1/2] Add debug logging to GraphQL owner/repo and search query extraction Add logGraphQL calls to the extractOwnerRepo and extractSearchQuery helper functions in internal/proxy/graphql.go to make the multi-step extraction process observable during debugging. - extractOwnerRepo: log values found in request variables - extractOwnerRepo: log values extracted via query regex fallback - extractSearchQuery: log search query found in variables - extractSearchQuery: log search query found inline in the query text - extractSearchQuery: log when no search query is found These logs activate only when DEBUG=proxy:graphql (or DEBUG=*) is set, adding zero overhead in production while enabling precise tracing of why a particular GraphQL request ends up with a specific owner/repo/query label. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- internal/proxy/graphql.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/proxy/graphql.go b/internal/proxy/graphql.go index 421eb473..3f0d8c56 100644 --- a/internal/proxy/graphql.go +++ b/internal/proxy/graphql.go @@ -155,6 +155,7 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s if v, ok := variables["repo"].(string); ok && repo == "" { repo = v } + logGraphQL.Printf("extractOwnerRepo: from variables: owner=%q repo=%q", owner, repo) } // Fall back to parsing the query string @@ -166,6 +167,7 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s if m[2] != "" && repo == "" { repo = m[2] } + logGraphQL.Printf("extractOwnerRepo: from query regex: owner=%q repo=%q", owner, repo) } } @@ -193,13 +195,16 @@ func extractSearchQuery(query string, variables map[string]interface{}) string { // Check variables for $query if variables != nil { if v, ok := variables["query"].(string); ok && v != "" { + logGraphQL.Printf("extractSearchQuery: found in variables: %.80s", v) return v } } // Parse inline: search(query:"repo:owner/name is:issue", ...) if m := searchQueryArgPattern.FindStringSubmatch(query); m != nil { + logGraphQL.Printf("extractSearchQuery: found inline: %.80s", m[1]) return m[1] } + logGraphQL.Print("extractSearchQuery: no search query found") return "" } From 108772e7abadc045a53f81e6f7b808947f6aeba4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:52:43 +0000 Subject: [PATCH 2/2] fix: use %q with truncateForLog for safe debug logging of user-controlled search query values Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/985634c1-dde7-42d6-b1bb-258bd55d1f76 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- internal/proxy/graphql.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/proxy/graphql.go b/internal/proxy/graphql.go index 3f0d8c56..10020965 100644 --- a/internal/proxy/graphql.go +++ b/internal/proxy/graphql.go @@ -189,19 +189,31 @@ func extractOwnerRepo(variables map[string]interface{}, query string) (string, s // searchQueryArgPattern extracts the literal query string from search(query:"...", ...) var searchQueryArgPattern = regexp.MustCompile(`(?i)\bsearch\s*\(\s*query\s*:\s*"([^"]+)"`) +// truncateForLog truncates s to at most maxRunes runes, for safe debug logging. +func truncateForLog(s string, maxRunes int) string { + if maxRunes <= 0 { + return "" + } + r := []rune(s) + if len(r) <= maxRunes { + return s + } + return string(r[:maxRunes]) +} + // extractSearchQuery returns the search query argument from a GraphQL search // query. It checks variables ($query) first, then inline query text. func extractSearchQuery(query string, variables map[string]interface{}) string { // Check variables for $query if variables != nil { if v, ok := variables["query"].(string); ok && v != "" { - logGraphQL.Printf("extractSearchQuery: found in variables: %.80s", v) + logGraphQL.Printf("extractSearchQuery: found in variables: %q", truncateForLog(v, 80)) return v } } // Parse inline: search(query:"repo:owner/name is:issue", ...) if m := searchQueryArgPattern.FindStringSubmatch(query); m != nil { - logGraphQL.Printf("extractSearchQuery: found inline: %.80s", m[1]) + logGraphQL.Printf("extractSearchQuery: found inline: %q", truncateForLog(m[1], 80)) return m[1] } logGraphQL.Print("extractSearchQuery: no search query found")