gastownhall/beads · error
loading team labels: %w
Error message
loading team labels: %w
What it means
Returned by Tracker.CreateIssue when BuildLabelCache fails to fetch the target Linear team's labels via the GraphQL API. The label cache is needed to translate beads labels into Linear label IDs before creating the issue, so a fetch failure aborts creation.
Source
Thrown at internal/linear/tracker.go:200
return nil, nil
}
func (t *Tracker) CreateIssue(ctx context.Context, issue *types.Issue) (*tracker.TrackerIssue, error) {
client := t.primaryClient()
if client == nil {
return nil, fmt.Errorf("no Linear client available")
}
priority := PriorityToLinear(issue.Priority, t.config)
stateID, err := t.findStateID(ctx, client, issue.Status)
if err != nil {
return nil, fmt.Errorf("finding state for status %s: %w", issue.Status, err)
}
labelCache, err := BuildLabelCache(ctx, client)
if err != nil {
return nil, fmt.Errorf("loading team labels: %w", err)
}
labelIDs, unknown := ResolveLabelIDs(issue, labelCache, t.config)
for _, name := range unknown {
fmt.Fprintf(os.Stderr, "linear: bead %s: label %q not found on Linear team (skipped)\n", issue.ID, name)
}
// Use issue.Description as-is: the sync engine's FormatDescription hook
// (BuildLinearDescription) has already merged AcceptanceCriteria/Design/Notes
// into the description before calling CreateIssue. Calling BuildLinearDescription
// here a second time would duplicate those sections for issues with structured fields.
description := issue.Description
// Use idempotent creation when we have enough bead metadata to generate
// a stable marker. This prevents duplicate Linear issues when sync is
// interrupted between the API create call and the local external_ref
// write-back.
if issue.ID != "" && issue.CreatedBy != "" {
marker := GenerateIdempotencyMarker(issue.ID, issue.CreatedBy, issue.CreatedAt.UnixNano())View on GitHub (pinned to 71377f2769)
Solutions
- Check the LINEAR_API_KEY / OAuth credentials are valid and can read team labels
- Retry the operation — label-cache fetch failures are often transient (rate limits, network blips)
- Verify the token's scopes include reading issue labels for the team
- Inspect the wrapped error returned in the %w chain for the concrete cause
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: verify the API key can read labels
client := linear.NewClient(apiKey)
if _, err := client.ListLabels(ctx); err != nil {
return fmt.Errorf("linear credentials/labels check failed: %w", err)
} Try / catch
created, err := tracker.CreateIssue(ctx, issue)
if err != nil && strings.Contains(err.Error(), "loading team labels") {
if retriable(err) {
time.Sleep(backoff)
created, err = tracker.CreateIssue(ctx, issue)
}
} Prevention
- Rotate API keys through a secret manager and update config promptly
- Grant the token label-read scope for all synced teams
- Use exponential backoff around sync operations
- Monitor Linear API status/uptime during sync windows
When it happens
Trigger: Tracker.CreateIssue called when the Linear labels query fails: invalid or expired API key, network error, rate limiting, or the token lacking scope to read team labels.
Common situations: Rotated Linear API key not updated in env/config; OAuth token missing label read scope; corporate proxy blocking Linear API; transient Linear API outage during sync.
Related errors
- fetching issues from team %s: %w
- building label cache for team %s: %w
- fetching workflow states for team %s: %w
- failed to summarize: %w
- failed to fetch issue %d: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5ed0aaffa8397c7e.
Report an issue: GitHub.