{"record":{"id":"165741b0b70b4797","repo":"charmbracelet/crush","slug":"failed-to-marshal-graphql-request-w","errorCode":null,"errorMessage":"failed to marshal GraphQL request: %w","messagePattern":"failed to marshal GraphQL request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/agent/tools/sourcegraph.go","lineNumber":106,"sourceCode":"\t\t\t\trequestCtx, cancel = context.WithTimeout(ctx, time.Duration(params.Timeout)*time.Second)\n\t\t\t\tdefer cancel()\n\t\t\t}\n\n\t\t\ttype graphqlRequest struct {\n\t\t\t\tQuery     string `json:\"query\"`\n\t\t\t\tVariables struct {\n\t\t\t\t\tQuery string `json:\"query\"`\n\t\t\t\t} `json:\"variables\"`\n\t\t\t}\n\n\t\t\trequest := graphqlRequest{\n\t\t\t\tQuery: \"query Search($query: String!) { search(query: $query, version: V2, patternType: keyword ) { results { matchCount, limitHit, resultCount, approximateResultCount, missing { name }, timedout { name }, indexUnavailable, results { __typename, ... on FileMatch { repository { name }, file { path, url, content }, lineMatches { preview, lineNumber, offsetAndLengths } } } } } }\",\n\t\t\t}\n\t\t\trequest.Variables.Query = params.Query\n\n\t\t\tgraphqlQueryBytes, err := json.Marshal(request)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to marshal GraphQL request: %w\", err)\n\t\t\t}\n\t\t\tgraphqlQuery := string(graphqlQueryBytes)\n\n\t\t\treq, err := http.NewRequestWithContext(\n\t\t\t\trequestCtx,\n\t\t\t\t\"POST\",\n\t\t\t\t\"https://sourcegraph.com/.api/graphql\",\n\t\t\t\tbytes.NewBuffer([]byte(graphqlQuery)),\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to create request: %w\", err)\n\t\t\t}\n\n\t\t\treq.Header.Set(\"Content-Type\", \"application/json\")\n\t\t\treq.Header.Set(\"User-Agent\", \"crush/1.0\")\n\n\t\t\tresp, err := client.Do(req)\n\t\t\tif err != nil {","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/sourcegraph.go#L88-L124","documentation":"Wraps a json.Marshal error while serializing the GraphQL request payload in the sourcegraph tool (internal/agent/tools/sourcegraph.go:104-107). The payload is a statically typed struct with a string query and string variable, so marshalling can practically never fail; this is a defensive branch that only fires if encoding/json itself errors, which for plain strings requires invalid UTF-8 in the query or an unrecoverable encoder state.","triggerScenarios":"json.Marshal(request) fails — in practice only if SourcegraphParams.Query contains invalid UTF-8 bytes (e.g. binary data passed by an LLM tool call into the query parameter), since all other fields are fixed strings.","commonSituations":"A model supplying a query with raw binary or invalid UTF-8 characters; almost never seen in normal operation because the struct contains no channels, funcs, cycles, or unsupported numeric types.","solutions":["Sanitize or validate params.Query as valid UTF-8 (utf8.ValidString) before building the request.","Log the raw query parameter from the tool call to identify where the malformed input originated.","Return a clear tool-level validation error for non-UTF-8 queries instead of a marshal failure."],"exampleFix":"// before\ngithubQueryBytes, err := json.Marshal(request)\n\n// after\nif !utf8.ValidString(params.Query) {\n    return fantasy.NewTextErrorResponse(\"query must be valid UTF-8\"), nil\n}\ngraphqlQueryBytes, err := json.Marshal(request)","handlingStrategy":"validation","validationCode":"if !utf8.ValidString(params.Query) {\n    return fantasy.NewTextErrorResponse(\"query must be valid UTF-8\"), nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := json.Marshal(request); err != nil {\n    log.Printf(\"marshal failed for query %q\", params.Query)\n    return err\n}","preventionTips":["Sanitize tool-call string parameters as UTF-8 before use.","Treat this error as a sign of binary input from the LLM and clamp/reject such queries.","Keep the request struct free of unsupported types (funcs, channels, cycles)."],"tags":["json","encoding","graphql","go"],"backgroundTag":"json-marshal-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}