{"record":{"id":"c611f182022198b5","repo":"gastownhall/beads","slug":"failed-to-parse-update-response-w-c611f1","errorCode":null,"errorMessage":"failed to parse update response: %w","messagePattern":"failed to parse update response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1015,"sourceCode":"\t\t}\n\t`\n\n\treq := &GraphQLRequest{\n\t\tQuery: query,\n\t\tVariables: map[string]interface{}{\n\t\t\t\"id\":    issueID,\n\t\t\t\"input\": updates,\n\t\t},\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to update issue: %w\", err)\n\t}\n\n\tvar updateResp IssueUpdateResponse\n\tif err := json.Unmarshal(data, &updateResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse update response: %w\", err)\n\t}\n\n\tif !updateResp.IssueUpdate.Success {\n\t\treturn nil, fmt.Errorf(\"issue update reported as unsuccessful\")\n\t}\n\n\treturn &updateResp.IssueUpdate.Issue, nil\n}\n\n// BatchCreateIssues creates multiple issues in Linear using the issueBatchCreate mutation.\n// Inputs are chunked into groups of BatchSize (50).\n//\n// On ambiguous failure (API error or success=false), this method does NOT blindly\n// retry the full chunk—Linear may have partially applied the mutation. Instead it\n// searches for each issue's idempotency marker (embedded in the description) to\n// discover which issues were actually created, and returns an error for the rest.\nfunc (c *Client) BatchCreateIssues(ctx context.Context, inputs []IssueCreateInput) ([]Issue, error) {\n\tif len(inputs) == 0 {","sourceCodeStart":997,"sourceCodeEnd":1033,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L997-L1033","documentation":"UpdateIssue calls the Linear issueUpdate GraphQL mutation via c.Execute and then json.Unmarshals the returned raw JSON into IssueUpdateResponse. This error means the HTTP call succeeded but the response body could not be decoded into the expected envelope (missing issueUpdate field, unexpected shape, or non-JSON payload such as an HTML error page from a proxy). The library throws it to distinguish transport failures from parse failures.","triggerScenarios":"Calling Client.UpdateIssue(ctx, issueID, updates) when Linear (or an intermediary) returns a body that is not valid JSON or does not match the IssueUpdateResponse struct (e.g. a partial success payload, an HTML gateway error page, or a changed GraphQL schema).","commonSituations":"Corporate proxies or load balancers returning HTML 502/503 pages with HTTP 200-style handling; Linear API schema changes renaming issueUpdate; truncated response bodies on flaky networks; a custom HTTP transport in tests returning unexpected fixtures.","solutions":["Print/log the raw response (data) alongside the wrapped error to see what actually came back before changing code.","Retry UpdateIssue; a truncated or proxy-generated body is usually transient.","Verify you are on a recent version of the library matching the current Linear GraphQL schema.","Check network middleboxes (corporate proxy, API gateway) that can substitute HTML error bodies for JSON."],"exampleFix":"// before\nissue, err := client.UpdateIssue(ctx, issueID, updates)\nif err != nil {\n    return err\n}\n// after\nissue, err := client.UpdateIssue(ctx, issueID, updates)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to parse update response\") {\n        // inspect raw payload / retry transient parse failures\n        return fmt.Errorf(\"linear update response undecodable: %w\", err)\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// No pre-call validation can detect a bad response body; ensure inputs are JSON-serializable\nif updates == nil {\n    return errors.New(\"updates input must not be nil\")\n}","typeGuard":null,"tryCatchPattern":"issue, err := client.UpdateIssue(ctx, id, updates)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to parse update response\") {\n        // transient/undecodable body: log raw payload if available, retry once\n        return retryUpdate(ctx, client, id, updates)\n    }\n    return err\n}","preventionTips":["Keep the library version aligned with the Linear API version you target.","Avoid routing api.linear.app traffic through proxies that inject HTML error pages.","Distinguish parse failures from success=false failures in your error handling."],"tags":["json","parsing","graphql","network","linear-api"],"backgroundTag":"json-parse-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}