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.

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)

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.