gastownhall/beads · error
fetching workflow states for team %s: %w
Error message
fetching workflow states for team %s: %w
What it means
While validating push mappings, the tracker fetches Linear's workflow states for each configured team to resolve state IDs. This error wraps any failure from BuildStateCache (network errors, auth failures, API errors) with the team ID for context. It means the validation could not even see what states exist for that team.
Source
Thrown at internal/linear/tracker.go:627
return fmt.Errorf("%s", missingExplicitStateMapMessage)
}
statuses := []types.Status{
types.StatusOpen,
types.StatusInProgress,
types.StatusBlocked,
types.StatusClosed,
types.StatusDeferred,
types.StatusPinned,
types.StatusHooked,
}
for _, teamID := range t.teamIDs {
client := t.clients[teamID]
if client == nil {
continue
}
cache, err := BuildStateCache(ctx, client)
if err != nil {
return fmt.Errorf("fetching workflow states for team %s: %w", teamID, err)
}
for _, status := range statuses {
if _, err := ResolveStateIDForBeadsStatus(cache, status, t.config); err != nil {
if skipOptionalPushStateMapping(status, err, t.config.CustomStatuses) {
continue
}
return err
}
}
for _, cs := range t.config.CustomStatuses {
st := types.Status(cs.Name)
if _, err := ResolveStateIDForBeadsStatus(cache, st, t.config); err != nil {
if skipOptionalPushStateMapping(st, err, t.config.CustomStatuses) {
continue
}
return err
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Verify connectivity to Linear's API and retry the sync/push.
- Check that the Linear API key in the config is valid and has not expired; re-run 'bd linear link' if needed.
- Confirm each configured team ID still exists in Linear and remove/update stale teams.
- Read the wrapped inner error (%w) for the precise API/network cause.
Example fix
// before
err := tracker.ValidatePushStateMappings(ctx) // wraps: fetching workflow states for team X
// after
if err := tracker.ValidatePushStateMappings(ctx); err != nil {
log.Printf("linear validation failed: %v", err) // inspect wrapped cause
}
// ensure API key valid, then retry Defensive patterns
Strategy: retry
Validate before calling
if err := client.Ping(ctx); err != nil {
return fmt.Errorf("linear API unreachable before sync: %w", err)
} Try / catch
if err := tracker.ValidatePushStateMappings(ctx); err != nil {
var netErr net.Error
if errors.As(err, &netErr) || errors.Is(err, context.DeadlineExceeded) {
return retryWithBackoff(ctx, op)
}
return err
} Prevention
- Rotate and test the Linear API key regularly.
- Check team IDs after renaming/deleting teams in Linear.
- Add retry-with-backoff around Linear API operations.
When it happens
Trigger: BuildStateCache(ctx, client) returns an error during ValidatePushStateMappings for a given teamID — typically when the Linear GraphQL API is unreachable, the API key is invalid/expired, or the team ID no longer exists.
Common situations: Expired or rotated Linear API key; offline/VPN-blocked environment; team deleted or renamed in Linear so the configured team ID is stale; Linear API outage or rate limiting.
Related errors
- fetching issues from team %s: %w
- loading team labels: %w
- failed to summarize: %w
- failed to fetch issue %d: %w
- max retries (%d) exceeded: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/67b311cff00c871a.
Report an issue: GitHub.