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

  1. Check the LINEAR_API_KEY / OAuth credentials are valid and can read team labels
  2. Retry the operation — label-cache fetch failures are often transient (rate limits, network blips)
  3. Verify the token's scopes include reading issue labels for the team
  4. 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

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


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