{"record":{"id":"0254751ae841ca8d","repo":"gastownhall/beads","slug":"failed-to-update-project-w","errorCode":null,"errorMessage":"failed to update project: %w","messagePattern":"failed to update project: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1579,"sourceCode":"\t\t\t\t\tstate\n\t\t\t\t\tprogress\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\":    projectID,\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 project: %w\", err)\n\t}\n\n\tvar updateResp ProjectUpdateResponse\n\tif err := json.Unmarshal(data, &updateResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse update project response: %w\", err)\n\t}\n\n\tif !updateResp.ProjectUpdate.Success {\n\t\treturn nil, fmt.Errorf(\"project update reported as unsuccessful\")\n\t}\n\n\treturn &updateResp.ProjectUpdate.Project, nil\n}\n","sourceCodeStart":1561,"sourceCodeEnd":1593,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L1561-L1593","documentation":"UpdateProject wraps any error returned by the GraphQL Execute call (network failure, HTTP error, or GraphQL errors array) with the context 'failed to update project'. The underlying error is preserved via %w so callers can unwrap with errors.Is/As. It signals the Linear API rejected or never received the project mutation.","triggerScenarios":"Calling linear Client.UpdateProject when the Linear API is unreachable, the API key is invalid/expired, the project ID does not exist, a rate limit is hit, or the GraphQL response carries an errors array.","commonSituations":"Revoked Linear API keys, offline/timeout network conditions, updating a project that was deleted or that the integration token cannot access, Linear API downtime, exceeded GraphQL complexity or rate limits.","solutions":["Inspect the wrapped error with errors.Unwrap (or %v logging) to see the actual transport/GraphQL failure.","Verify the Linear API key is valid and has access to the target project/team.","Check that the project ID passed to UpdateProject still exists (fetch it first via the API).","Retry with backoff if the wrapped error is a 429 rate-limit or transient network error.","Check Linear's status page for API outages."],"exampleFix":"// before\nproject, err := client.UpdateProject(ctx, id, updates)\nif err != nil {\n\tlog.Fatal(err)\n}\n// after\nproject, err := client.UpdateProject(ctx, id, updates)\nif err != nil {\n\tvar gqlErr *linear.GraphQLError\n\tif errors.As(err, &gqlErr) {\n\t\tlog.Fatalf(\"linear rejected project update: %v\", gqlErr)\n\t}\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\tlog.Fatal(\"linear API timed out; retry later\")\n\t}\n\tlog.Fatal(err)\n}","handlingStrategy":"try-catch","validationCode":"if projectID == \"\" {\n\treturn fmt.Errorf(\"project ID required before UpdateProject\")\n}\nif client == nil || apiKey == \"\" {\n\treturn fmt.Errorf(\"linear client/key must be configured before UpdateProject\")\n}","typeGuard":null,"tryCatchPattern":"project, err := client.UpdateProject(ctx, id, updates)\nif err != nil {\n\tvar netErr net.Error\n\tswitch {\n\tcase errors.As(err, &netErr) || errors.Is(err, context.DeadlineExceeded):\n\t\t// retry with backoff\n\tcase strings.Contains(err.Error(), \"429\"):\n\t\t// honor rate limit, retry later\n\tdefault:\n\t\treturn fmt.Errorf(\"update project %s: %w\", id, err)\n\t}\n}","preventionTips":["Always unwrap/log the wrapped cause before reporting, since %w preserves the real error.","Validate project IDs exist (via a fetch) before updating.","Keep the API key in env/secret store and rotate before expiry.","Implement backoff retry for 429 and transient network errors.","Pin and monitor the Linear API version you depend on."],"tags":["linear","graphql","api-error","network"],"backgroundTag":"graphql-mutation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}