{"record":{"id":"938f53d1792c8a3a","repo":"gastownhall/beads","slug":"failed-to-fetch-teams-w","errorCode":null,"errorMessage":"failed to fetch teams: %w","messagePattern":"failed to fetch teams: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":1428,"sourceCode":"\tquery := `\n\t\tquery {\n\t\t\tteams {\n\t\t\t\tnodes {\n\t\t\t\t\tid\n\t\t\t\t\tname\n\t\t\t\t\tkey\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`\n\n\treq := &GraphQLRequest{\n\t\tQuery: query,\n\t}\n\n\tdata, err := c.Execute(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to fetch teams: %w\", err)\n\t}\n\n\tvar teamsResp TeamsResponse\n\tif err := json.Unmarshal(data, &teamsResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse teams response: %w\", err)\n\t}\n\n\treturn teamsResp.Teams.Nodes, nil\n}\n\n// FetchProjects retrieves projects from Linear with optional filtering by state.\n// state can be: \"planned\", \"started\", \"paused\", \"completed\", \"canceled\", or \"all\"/\"\".\nfunc (c *Client) FetchProjects(ctx context.Context, state string) ([]Project, error) {\n\tvar allProjects []Project\n\tvar cursor string\n\n\tfilter := map[string]interface{}{\n\t\t\"team\": map[string]interface{}{","sourceCodeStart":1410,"sourceCodeEnd":1446,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L1410-L1446","documentation":"FetchTeams queries the teams GraphQL field to discover team IDs. This error wraps any Execute failure — network errors, HTTP status errors, GraphQL errors like insufficient scopes — when listing teams. It is typically the first call made when configuring the integration, so it is the first place auth problems surface.","triggerScenarios":"c.Execute fails on `query { teams { nodes { id name key } } }`: invalid/expired API key (401), token missing teams read scope, rate limiting, network unreachable, or context cancellation.","commonSituations":"Initial setup with a mistyped LINEAR_API_KEY; org admin revoked the integration token; workspace SSO enforcing token rotation; firewall blocking linear.app; expired OAuth token in a long-lived daemon.","solutions":["Unwrap the error to identify the underlying cause (status code / GraphQL message).","Verify the API key in Linear settings → API; regenerate if revoked and update the environment/config.","Test connectivity: curl the Linear GraphQL endpoint from the same host.","Check for 429 rate-limit errors and add backoff/retry around the call.","Ensure the token's OAuth scopes include team read access."],"exampleFix":"// before\nteam, err := client.FetchTeams(ctx)\n// after\nteam, err := client.FetchTeams(ctx)\nif err != nil {\n    var rl *RateLimitError\n    if errors.As(err, &rl) { time.Sleep(rl.RetryAfter); return client.FetchTeams(ctx) }\n    return fmt.Errorf(\"team discovery failed (check LINEAR_API_KEY): %w\", err)\n}","handlingStrategy":"retry","validationCode":"// sanity-check configuration before calling\nif os.Getenv(\"LINEAR_API_KEY\") == \"\" {\n    return fmt.Errorf(\"LINEAR_API_KEY not set\")\n}\nif len(os.Getenv(\"LINEAR_API_KEY\")) < 20 {\n    return fmt.Errorf(\"LINEAR_API_KEY looks truncated\")\n}","typeGuard":null,"tryCatchPattern":"teams, err := client.FetchTeams(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"401\") || strings.Contains(err.Error(), \"authentication\") {\n        return fmt.Errorf(\"invalid or expired Linear API key: %w\", err)\n    }\n    if isRetryable(err) {\n        return retryWithBackoff(3, 2*time.Second, func() error {\n            _, err = client.FetchTeams(ctx); return err\n        })\n    }\n    return err\n}","preventionTips":["Use FetchTeams as the canonical setup-time health check for the token.","Add exponential backoff with jitter for 429 responses.","Store the API key in a secret manager; check expiry/rotation on daemon startup.","Give the context a timeout so hung connections fail fast and retryably."],"tags":["go","graphql","network","authentication","linear-api"],"backgroundTag":"graphql-request-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}