gastownhall/beads · error

Linear authentication not configured Options: OAuth (for C

Error message

Linear authentication not configured
Options:
  OAuth (for CI):  export LINEAR_OAUTH_CLIENT_ID=... LINEAR_OAUTH_CLIENT_SECRET=...
  API key (devs):  export LINEAR_API_KEY=... or bd config set linear.api_key "..."

What it means

buildLinearClient constructs the Linear API client. It first tries OAuth config (env vars or linear.oauth_client_id/secret), then falls back to linear.api_key. If no API key is present and OAuth wasn't detected, it returns this authentication-not-configured error (note: unlike error 973, this message omits the `bd config set linear.api_key` hint variant with YOUR_API_KEY).

Source

Thrown at cmd/bd/linear.go:1183

// buildLinearClient resolves auth credentials and returns an appropriately
// configured Linear client. OAuth takes precedence over API key.
func buildLinearClient(ctx context.Context, teamID string) (*linear.Client, error) {
	oauthClientID, _ := getLinearConfig(ctx, "linear.oauth_client_id")
	oauthClientSecret, _ := getLinearConfig(ctx, "linear.oauth_client_secret")

	if oauthClientID != "" && oauthClientSecret != "" {
		debug.Logf("Linear: using OAuth client-credentials authentication")
		oauthCfg := linear.OAuthConfig{
			ClientID:     oauthClientID,
			ClientSecret: oauthClientSecret,
		}
		return linear.NewOAuthClient(oauthCfg, teamID), nil
	}

	apiKey, _ := getLinearConfig(ctx, "linear.api_key")
	if apiKey == "" {
		return nil, fmt.Errorf("Linear authentication not configured\n" +
			"Options:\n" +
			"  OAuth (for CI):  export LINEAR_OAUTH_CLIENT_ID=... LINEAR_OAUTH_CLIENT_SECRET=...\n" +
			"  API key (devs):  export LINEAR_API_KEY=... or bd config set linear.api_key \"...\"")
	}

	return linear.NewClient(apiKey, teamID), nil
}

// storeConfigLoader adapts the store to the linear.ConfigLoader interface.
type storeConfigLoader struct {
	ctx context.Context
}

func (l *storeConfigLoader) GetAllConfig() (map[string]string, error) {
	return store.GetAllConfig(l.ctx)
}

// loadLinearMappingConfig loads mapping configuration from beads config.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Export LINEAR_API_KEY or run `bd config set linear.api_key "YOUR_API_KEY"`
  2. For CI, export both LINEAR_OAUTH_CLIENT_ID and LINEAR_OAUTH_CLIENT_SECRET (a single one is insufficient)
  3. Confirm with `bd config list` / `env | grep LINEAR` that credentials are visible to the bd process

Example fix

// before
export LINEAR_OAUTH_CLIENT_ID=...   # secret missing
// after
export LINEAR_OAUTH_CLIENT_ID=...
export LINEAR_OAUTH_CLIENT_SECRET=...
Defensive patterns

Strategy: validation

Validate before calling

ok := (os.Getenv("LINEAR_OAUTH_CLIENT_ID") != "" && os.Getenv("LINEAR_OAUTH_CLIENT_SECRET") != "") ||
	os.Getenv("LINEAR_API_KEY") != ""
if !ok {
	return errors.New("Linear credentials missing: export LINEAR_API_KEY or OAuth client id+secret")
}

Try / catch

client, err := buildLinearClient(ctx, teamID)
if err != nil && strings.Contains(err.Error(), "authentication not configured") {
	return fmt.Errorf("export LINEAR_API_KEY (or both OAuth vars) and retry: %w", err)
}

Prevention

When it happens

Trigger: Calling getLinearClient or runLinearTeams when neither LINEAR_OAUTH_CLIENT_ID+SECRET (nor config equivalents) nor LINEAR_API_KEY / linear.api_key are set.

Common situations: Fresh install; CI job secrets not exported to the bd process; user set only one of the two OAuth variables (both are required for hasOAuth); API key stored in the wrong config namespace.

Understand the failure class

Related errors


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