{"record":{"id":"d72edf9327a997da","repo":"gastownhall/beads","slug":"failed-to-update-issue-w-d72edf","errorCode":null,"errorMessage":"failed to update issue: %w","messagePattern":"failed to update issue: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1010,"sourceCode":"\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t\tupdatedAt\n\t\t\t\t}\n\t\t\t}\n\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","sourceCodeStart":992,"sourceCodeEnd":1028,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L992-L1028","documentation":"UpdateIssue builds an issueUpdate GraphQL mutation and executes it via c.Execute; if Execute returns any error (transport failure, HTTP non-2xx, GraphQL errors, parse failure), it is wrapped as 'failed to update issue'. This is the top-level wrapper for all update-path failures; unwrap it to find the root cause.","triggerScenarios":"Invalid issueID (nonexistent/archived issue) producing a GraphQL error; trying to set an invalid stateID/label/assignee in updates; network failure or 429 rate limit during the mutation; token lacking update scope.","commonSituations":"Issue deleted or moved to trash by a user while the automation was running; stale IDs cached from earlier queries; bulk update loops tripping Linear's rate limiter; integration tokens without write scope.","solutions":["Unwrap with errors.As/Unwrap to see whether it's transport, HTTP status, or a GraphQL error","Verify issueID and all update field values (stateID, assigneeID, labelIDs) are current and in the same workspace","Handle 429 by throttling bulk updates with backoff","Ensure the API token has write scopes for issue updates"],"exampleFix":"// before\n_, err := client.UpdateIssue(ctx, issueID, linear.IssueUpdateInput{StateID: cachedStateID})\n// after\nstateID := refreshStateIDFromAPI(ctx, client, teamID) // don't trust stale cached IDs\n_, err := client.UpdateIssue(ctx, issueID, linear.IssueUpdateInput{StateID: stateID})\nif err != nil {\n    var ge *linear.GraphQLError\n    if errors.As(err, &ge) { /* handle field-specific GraphQL error */ }\n}","handlingStrategy":"try-catch","validationCode":"// verify the issue still exists and IDs are valid before updating\nissues, err := client.SearchIssues(ctx, fmt.Sprintf(\"id: %s\", issueID))\nif err != nil || len(issues) == 0 {\n    return fmt.Errorf(\"issue %s not found, skipping update\", issueID)\n}","typeGuard":null,"tryCatchPattern":"_, err := client.UpdateIssue(ctx, issueID, updates)\nif err != nil {\n    unwrapped := fmt.Errorf(\"%v\", errors.Unwrap(err))\n    switch {\n    case strings.Contains(unwrapped.Error(), \"status 429\"):\n        backoffAndRetry()\n    case strings.Contains(unwrapped.Error(), \"GraphQL errors\"):\n        log.Printf(\"update rejected, check IDs/scopes: %v\", unwrapped)\n    default:\n        return err\n    }\n}","preventionTips":["Re-fetch issue IDs near update time instead of long-lived caches","Throttle bulk updates to stay under Linear rate limits","Ensure the token has issue write scopes","Handle deleted/archived issues gracefully in automations"],"tags":["graphql","api-error","update"],"backgroundTag":"issue-update-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}