{"record":{"id":"136853c6163b8b7c","repo":"gastownhall/beads","slug":"failed-to-create-issue-w-136853","errorCode":null,"errorMessage":"failed to create issue: %w","messagePattern":"failed to create issue: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":850,"sourceCode":"\tif stateID != \"\" {\n\t\tinput[\"stateId\"] = stateID\n\t}\n\tif len(labelIDs) > 0 {\n\t\tinput[\"labelIds\"] = labelIDs\n\t}\n\treturn input\n}\n\n// CreateIssue creates a new issue in Linear.\nfunc (c *Client) CreateIssue(ctx context.Context, title, description string, priority int, stateID string, labelIDs []string) (*Issue, error) {\n\treq := &GraphQLRequest{\n\t\tQuery:     issueCreateMutation,\n\t\tVariables: map[string]interface{}{\"input\": c.buildIssueCreateInput(title, description, priority, stateID, labelIDs)},\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create issue: %w\", err)\n\t}\n\n\tvar createResp IssueCreateResponse\n\tif err := json.Unmarshal(data, &createResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse create response: %w\", err)\n\t}\n\n\tif !createResp.IssueCreate.Success {\n\t\treturn nil, fmt.Errorf(\"issue creation reported as unsuccessful\")\n\t}\n\n\treturn &createResp.IssueCreate.Issue, nil\n}\n\n// createIssueSingleAttempt executes the issueCreate mutation exactly once,\n// without the retry loop used by Execute. This is intentional: retrying a\n// mutation that may have already reached Linear risks creating a duplicate.\n// The caller (CreateIssueIdempotent) handles retry safety by re-searching for","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L832-L868","documentation":"CreateIssue sends the issueCreate GraphQL mutation and wraps any Execute failure with this message. It distinguishes transport/GraphQL failures from application-level 'creation unsuccessful' responses handled later.","triggerScenarios":"Execute fails during the issueCreate mutation: network timeout, 401 from a bad API key, 429 rate limit, GraphQL validation errors from an invalid input (bad state ID, nonexistent label IDs, missing required fields in the input map), or duplicate-subscription GraphQL errors.","commonSituations":"Passing stale workflow-state or label UUIDs (deleted since cached), invalid priority enum value, expired API key, network blips during automated `bd`-to-Linear sync runs.","solutions":["Unwrap the root cause to identify transport vs. GraphQL validation errors.","Verify every ID in the input (stateID, labelIDs) is currently valid via the Linear API.","Check the API key validity and scopes.","Retry with backoff on 429 or transient network errors; use CreateIssueIdempotent to avoid duplicates on retry."],"exampleFix":"// before\nif err != nil {\n    return nil, fmt.Errorf(\"failed to create issue: %w\", err)\n}\n// after\nif err != nil {\n    var gqlErr *GraphQLValidationError\n    if errors.As(err, &gqlErr) {\n        return nil, fmt.Errorf(\"failed to create issue (input: state=%s labels=%v): %w\", stateID, labelIDs, err)\n    }\n    return nil, fmt.Errorf(\"failed to create issue: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// validate referenced IDs before the mutation\nif stateID != \"\" && !uuidRegex.MatchString(stateID) {\n    return fmt.Errorf(\"invalid state ID: %q\", stateID)\n}\nfor _, id := range labelIDs {\n    if !uuidRegex.MatchString(id) {\n        return fmt.Errorf(\"invalid label ID: %q\", id)\n    }\n}","typeGuard":null,"tryCatchPattern":"issue, err := client.CreateIssue(ctx, title, desc, pri, stateID, labelIDs)\nif err != nil {\n    if isRateLimit(err) {\n        time.Sleep(backoff); return retry()\n    }\n    return fmt.Errorf(\"issue %q not created: %w\", title, err)\n}","preventionTips":["Refresh state/label caches rather than holding stale UUIDs.","Prefer CreateIssueIdempotent to make retries safe.","Validate priority is in Linear's accepted range (0–4).","Preflight API key and workspace access at startup."],"tags":["network","graphql","linear","mutation"],"backgroundTag":"api-request-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}