{"record":{"id":"a6ea5a6244213d2c","repo":"gastownhall/beads","slug":"no-states-found-for-team","errorCode":null,"errorMessage":"no states found for team","messagePattern":"no states found for team","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":654,"sourceCode":"\treq := &GraphQLRequest{\n\t\tQuery: query,\n\t\tVariables: map[string]interface{}{\n\t\t\t\"teamId\": c.TeamID,\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 fetch team states: %w\", err)\n\t}\n\n\tvar teamResp TeamResponse\n\tif err := json.Unmarshal(data, &teamResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse team states response: %w\", err)\n\t}\n\n\tif teamResp.Team.States == nil {\n\t\treturn nil, fmt.Errorf(\"no states found for team\")\n\t}\n\n\treturn teamResp.Team.States.Nodes, nil\n}\n\n// GetTeamLabels returns all issue labels defined for the team (paginated).\nfunc (c *Client) GetTeamLabels(ctx context.Context) ([]Label, error) {\n\tconst pageSize = 250\n\tquery := `\n\t\tquery TeamLabels($teamId: String!, $first: Int!, $after: String) {\n\t\t\tteam(id: $teamId) {\n\t\t\t\tlabels(first: $first, after: $after) {\n\t\t\t\t\tnodes {\n\t\t\t\t\t\tid\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t\tpageInfo {\n\t\t\t\t\t\thasNextPage","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L636-L672","documentation":"GetTeamStates fetches a team's workflow states via the Linear GraphQL API and decodes the response into a TeamResponse. If the JSON parses but the team's `states` field is nil, the client cannot distinguish 'team has no states' from a malformed response, so it returns this error rather than a nil pointer later.","triggerScenarios":"The GraphQL response decodes successfully but team.states is null — e.g. the team ID is invalid, the API token lacks access to the team, the query shape no longer matches the Linear schema, or the response is a partial GraphQL error payload where data.team is present but states is missing.","commonSituations":"Wrong or stale team UUID configured (pointing at a deleted/renamed team), API key scoped to a different team/workspace, Linear schema changes renaming or nesting the `states` field, or a GraphQL errors array returned alongside partial data.","solutions":["Verify the team ID used to build the query resolves — run the same GraphQL query manually with the same API key (curl/Altair) and inspect whether data.team.states comes back null.","Check the API key scope/permissions — regenerate a Linear API key with access to the target team.","Inspect the raw response for a GraphQL `errors` array and surface it instead of only checking nil.","Update the query/TeamResponse struct to match the current Linear GraphQL schema."],"exampleFix":"// before\nif teamResp.Team.States == nil {\n    return nil, fmt.Errorf(\"no states found for team\")\n}\n// after\nif teamResp.Team == nil || teamResp.Team.States == nil {\n    return nil, fmt.Errorf(\"no states found for team %q (check team ID and API key scope)\", c.TeamID)\n}","handlingStrategy":"validation","validationCode":"if teamID == \"\" || !uuidRegex.MatchString(teamID) {\n    return fmt.Errorf(\"invalid Linear team ID: %q\", teamID)\n}","typeGuard":"func hasStates(resp *linear.TeamResponse) bool {\n    return resp != nil && resp.Team != nil && resp.Team.States != nil\n}","tryCatchPattern":"states, err := client.GetTeamStates(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"no states found for team\") {\n        return fmt.Errorf(\"team %s unreachable or empty: %w\", teamID, err)\n    }\n    return err\n}","preventionTips":["Validate the team UUID format before calling GetTeamStates.","Cache team IDs resolved from viewer.teams rather than hardcoding.","Keep the API key in one place and verify its team access at startup.","Watch Linear changelog for workflowStates schema changes."],"tags":["graphql","linear","api-response","nil-check"],"backgroundTag":"empty-or-missing-api-response","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}