gastownhall/beads · error
failed to fetch team labels: %w
Error message
failed to fetch team labels: %w
What it means
GetTeamLabels calls Linear's GraphQL API page-by-page to collect all issue labels for a team. Any error returned from the underlying Execute call (transport failure, HTTP error, GraphQL error) is wrapped with this prefix so callers know the failure happened while fetching label pages.
Source
Thrown at internal/linear/client.go:699
var after *string
for {
vars := map[string]interface{}{
"teamId": c.TeamID,
"first": pageSize,
"after": nil,
}
if after != nil {
vars["after"] = *after
}
req := &GraphQLRequest{
Query: query,
Variables: vars,
}
data, err := c.Execute(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to fetch team labels: %w", err)
}
var page struct {
Team struct {
Labels *struct {
Nodes []Label `json:"nodes"`
PageInfo struct {
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
} `json:"pageInfo"`
} `json:"labels"`
} `json:"team"`
}
if err := json.Unmarshal(data, &page); err != nil {
return nil, fmt.Errorf("failed to parse team labels response: %w", err)
}
if page.Team.Labels == nil {
return nil, fmt.Errorf("no labels connection found for team")View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause (%w chain) for the actual transport/HTTP/GraphQL error and address it specifically.
- Verify the API key is valid and not expired by calling a trivial query (e.g. `viewer { id }`).
- Retry the call with backoff if the cause is a 429 or transient network error — Linear rate limits are documented in response headers.
- Check network/proxy configuration if the cause is connection-level (timeouts, DNS, TLS).
Example fix
// before
if err != nil {
return nil, fmt.Errorf("failed to fetch team labels: %w", err)
}
// after
if err != nil {
var rlErr *RateLimitError
if errors.As(err, &rlErr) {
time.Sleep(rlErr.RetryAfter)
continue // retry this page
}
return nil, fmt.Errorf("failed to fetch team labels (page %d): %w", pageNum, err)
} Defensive patterns
Strategy: retry
Validate before calling
if os.Getenv("LINEAR_API_KEY") == "" {
return errors.New("LINEAR_API_KEY not set")
}
// optional preflight:
// resp, err := http.Post(endpoint, ..., `{"query":"{ viewer { id } }"}`) Try / catch
labels, err := client.GetTeamLabels(ctx)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// retry with backoff
}
return fmt.Errorf("label cache build failed: %w", err)
} Prevention
- Preflight the API key with a trivial viewer query at startup.
- Implement exponential backoff for 429 responses.
- Run periodic health checks against api.linear.app.
- Log the unwrapped cause chain for faster diagnosis.
When it happens
Trigger: c.Execute fails during any pagination iteration: network timeout, non-2xx HTTP status, invalid/expired API key, rate limiting (429), or GraphQL errors in the response body.
Common situations: Expired or rotated LINEAR_API_KEY, corporate proxy/firewall blocking api.linear.app, Linear rate limits hit while paginating many label pages, transient DNS or TLS failures.
Related errors
- failed to search issues by description: %w
- failed to create issue: %w
- failed to update project: %w
- GraphQL request failed: %w
- failed to marshal request: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c75a4aafe72aa3fa.
Report an issue: GitHub.