gastownhall/beads · error

fetching issues from team %s: %w

Error message

fetching issues from team %s: %w

What it means

FetchIssues iterates the configured Linear teams and calls the per-team client's FetchIssues/FetchIssuesSince GraphQL query. If the remote fetch for a team fails, the partial results collected so far are returned alongside this error wrapping the underlying client error with the team ID. The Linear API error (rate limit, auth, network, GraphQL errors) is the wrapped cause.

Source

Thrown at internal/linear/tracker.go:151

	seen := make(map[string]bool)
	var result []tracker.TrackerIssue

	for _, teamID := range t.teamIDs {
		client := t.clients[teamID]
		if client == nil {
			continue
		}

		var issues []Issue
		var err error
		if opts.Since != nil {
			issues, err = client.FetchIssuesSince(ctx, state, *opts.Since)
		} else {
			issues, err = client.FetchIssues(ctx, state)
		}
		if err != nil {
			return result, fmt.Errorf("fetching issues from team %s: %w", teamID, err)
		}

		for _, li := range issues {
			if seen[li.ID] {
				continue
			}
			seen[li.ID] = true
			result = append(result, linearToTrackerIssue(&li))
		}
	}

	return result, nil
}

func (t *Tracker) FetchIssue(ctx context.Context, identifier string) (*tracker.TrackerIssue, error) {
	// Try the primary client first (first team), then others.
	for _, teamID := range t.teamIDs {
		client := t.clients[teamID]

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped cause (%w) — fix auth errors by refreshing LINEAR_API_KEY/OAuth credentials
  2. Retry on rate-limit/network errors; the client honors a configurable rate-limit floor (linear.rate_limit_floor) you can raise
  3. Verify the team ID is a valid Linear team key for your workspace
  4. Check network/proxy reachability to https://api.linear.app from the failing environment

Example fix

// before: one-shot fetch that dies on transient errors
issues, err := tr.FetchIssues(ctx, opts)
if err != nil { return err }
// after: retry with backoff
var issues []tracker.TrackerIssue
err := retry.Do(func() error {
    var e error
    issues, e = tr.FetchIssues(ctx, opts)
    return e
}, retry.Attempts(3), retry.Delay(2*time.Second))
Defensive patterns

Strategy: retry

Validate before calling

// Reachability pre-check before sync
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
resp, err := http.Get("https://api.linear.app/")
if err != nil { return fmt.Errorf("Linear unreachable: %w", err) }
resp.Body.Close()

Try / catch

issues, err := tr.FetchIssues(ctx, opts)
if err != nil {
    var teamErr string
    if strings.Contains(err.Error(), "fetching issues from team") {
        return retry.Do(func() error { // transient network/rate-limit
            issues, err = tr.FetchIssues(ctx, opts)
            return err
        }, retry.Attempts(3), retry.BackoffDelay)
    }
    return err
}

Prevention

When it happens

Trigger: Calling FetchIssues when a team's client request fails: expired/revoked API key, rate limiting, network outage or timeout, invalid team ID, or Linear GraphQL errors during FetchIssues/FetchIssuesSince.

Common situations: Rotated Linear API keys not updated in config; hitting Linear's rate limits during large initial syncs; corporate proxy/firewall blocking api.linear.app; typo'd team key that Linear rejects; transient DNS/network failures on CI.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/8c50ac4b8df7d29d. Report an issue: GitHub.