gastownhall/beads · error

Linear tracker not initialized

Error message

Linear tracker not initialized

What it means

Tracker.Validate is a precondition check: it succeeds only when Init has created at least one per-team client (len(t.clients) > 0). If the Tracker struct was never initialized — or Init failed or was skipped — the client map is empty and this error is returned. It is an internal lifecycle/liveness guard, not an API-level failure.

Solutions

  1. Ensure Tracker.Init(ctx, store) is called and its error handled before any other tracker method
  2. If Init failed, fix the underlying cause (missing credentials/team config) and retry Init
  3. Use the tracker registry (tracker.Register/lookup) so the tracker is constructed and initialized through the normal lifecycle
  4. In code, guard with tracker.Validate() and surface the error instead of proceeding to API calls

Example fix

// before: ignoring Init error
tracker := &linear.Tracker{}
_ = tracker.Init(ctx, store)
if err := tracker.Validate(); err != nil { ... }
// after
tracker := &linear.Tracker{}
if err := tracker.Init(ctx, store); err != nil {
    return fmt.Errorf("initializing linear tracker: %w", err)
}
if err := tracker.Validate(); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure lifecycle order before using the tracker
tracker := &linear.Tracker{}
if err := tracker.Init(ctx, store); err != nil {
    return fmt.Errorf("linear init: %w", err)
}
if err := tracker.Validate(); err != nil {
    return fmt.Errorf("linear validate: %w", err)
}

Try / catch

if err := tr.Validate(); err != nil {
    if strings.Contains(err.Error(), "not initialized") {
        return fmt.Errorf("call Tracker.Init before use: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Validate on a zero-value &linear.Tracker{} that never had Init called; calling Validate after a failed Init; or custom code constructing the Tracker directly instead of through the tracker registry and calling operations before Init.

Common situations: Embedding bd's linear tracker in other tooling and forgetting Init; error-swallowing wrappers that ignore Init's return error and proceed to Validate/sync; tests instantiating Tracker manually.

Related errors


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

Appendix: source

Thrown at internal/linear/tracker.go:121

		if endpoint != "" {
			client = client.WithEndpoint(endpoint)
		}
		if projectID != "" {
			client = client.WithProjectID(projectID)
		}
		if rateLimitFloor > 0 {
			client = client.WithRateLimitFloor(rateLimitFloor)
		}
		t.clients[teamID] = client
	}

	t.config = LoadMappingConfig(&configLoaderAdapter{ctx: ctx, store: store})
	return nil
}

func (t *Tracker) Validate() error {
	if len(t.clients) == 0 {
		return fmt.Errorf("Linear tracker not initialized")
	}
	return nil
}

func (t *Tracker) Close() error { return nil }

func (t *Tracker) FetchIssues(ctx context.Context, opts tracker.FetchOptions) ([]tracker.TrackerIssue, error) {
	state := opts.State
	if state == "" {
		state = "all"
	}

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

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

View on GitHub (pinned to 71377f2769)