{"record":{"id":"7f31e1c1de843f34","repo":"gastownhall/beads","slug":"linear-authentication-not-configured-options-oa-7f31e1","errorCode":null,"errorMessage":"Linear authentication not configured\nOptions:\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 \"YOUR_API_KEY\"","messagePattern":"Linear authentication not configured\nOptions:\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 \"YOUR_API_KEY\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/tracker.go","lineNumber":56,"sourceCode":"}\n\nfunc (t *Tracker) Name() string         { return \"linear\" }\nfunc (t *Tracker) DisplayName() string  { return \"Linear\" }\nfunc (t *Tracker) ConfigPrefix() string { return \"linear\" }\n\nfunc (t *Tracker) Init(ctx context.Context, store storage.Storage) error {\n\tt.store = store\n\n\t// Resolve authentication: OAuth client-credentials takes precedence over API key.\n\toauthClientID, _ := t.getConfig(ctx, \"linear.oauth_client_id\", \"LINEAR_OAUTH_CLIENT_ID\")\n\toauthClientSecret, _ := t.getConfig(ctx, \"linear.oauth_client_secret\", \"LINEAR_OAUTH_CLIENT_SECRET\")\n\thasOAuth := oauthClientID != \"\" && oauthClientSecret != \"\"\n\n\tvar apiKey string\n\tif !hasOAuth {\n\t\tapiKey, _ = t.getConfig(ctx, \"linear.api_key\", \"LINEAR_API_KEY\")\n\t\tif apiKey == \"\" {\n\t\t\treturn fmt.Errorf(\"Linear authentication not configured\\n\" +\n\t\t\t\t\"Options:\\n\" +\n\t\t\t\t\"  OAuth (for CI):  export LINEAR_OAUTH_CLIENT_ID=... LINEAR_OAUTH_CLIENT_SECRET=...\\n\" +\n\t\t\t\t\"  API key (devs):  export LINEAR_API_KEY=... or bd config set linear.api_key \\\"YOUR_API_KEY\\\"\")\n\t\t}\n\t}\n\n\t// Resolve team IDs: use pre-set IDs (from CLI), or fall back to config.\n\tif len(t.teamIDs) == 0 {\n\t\tpluralVal, _ := t.getConfig(ctx, \"linear.team_ids\", \"LINEAR_TEAM_IDS\")\n\t\tsingularVal, _ := t.getConfig(ctx, \"linear.team_id\", \"LINEAR_TEAM_ID\")\n\t\tt.teamIDs = tracker.ResolveProjectIDs(nil, pluralVal, singularVal)\n\t\tif len(t.teamIDs) == 0 {\n\t\t\treturn fmt.Errorf(\"Linear team ID not configured (set linear.team_id, linear.team_ids, or LINEAR_TEAM_ID)\")\n\t\t}\n\t}\n\n\t// Read optional endpoint and project ID.\n\tvar endpoint, projectID string","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/tracker.go#L38-L74","documentation":"Tracker.Init for the Linear integration requires credentials: either OAuth client credentials (linear.oauth_client_id + linear.oauth_client_secret, or LINEAR_OAUTH_* env vars) or an API key (linear.api_key config / config.yaml, or LINEAR_API_KEY env). If neither is present, Init returns this multi-line error listing both options and no clients are created.","triggerScenarios":"Calling Init (e.g. via `bd linear sync` or any linear tracker command) when: both LINEAR_OAUTH_CLIENT_ID and LINEAR_OAUTH_CLIENT_SECRET are unset, and neither `bd config set linear.api_key`/config.yaml nor LINEAR_API_KEY provides a value.","commonSituations":"Fresh clone without onboarding config; CI job where secrets were not injected into env; API key stored in config.yaml but running from a different working directory so yaml is not found; typo'd env var name (LINEAR_APIKEY, LINEAR_API_TOKEN).","solutions":["Set an API key: `bd config set linear.api_key \"YOUR_API_KEY\"` or export LINEAR_API_KEY","For CI, configure OAuth: export LINEAR_OAUTH_CLIENT_ID and LINEAR_OAUTH_CLIENT_SECRET","Verify env vars are actually visible to the bd process (e.g. `bd config get linear.api_key`, `echo $LINEAR_API_KEY`)","Check for typos in variable names and that you run bd from the workspace whose config.yaml holds the key"],"exampleFix":"// before: env var typo, nothing set\nexport LINEAR_APIKEY=lin_api_xxx\n// after\nexport LINEAR_API_KEY=lin_api_xxx\n# or persist it\nbd config set linear.api_key \"lin_api_xxx\"","handlingStrategy":"validation","validationCode":"// Fail fast with a clear message before running tracker commands\nif os.Getenv(\"LINEAR_API_KEY\") == \"\" &&\n    (os.Getenv(\"LINEAR_OAUTH_CLIENT_ID\") == \"\" || os.Getenv(\"LINEAR_OAUTH_CLIENT_SECRET\") == \"\") {\n    return fmt.Errorf(\"Linear credentials missing: set LINEAR_API_KEY or LINEAR_OAUTH_CLIENT_ID/SECRET\")\n}","typeGuard":null,"tryCatchPattern":"if err := tr.Init(ctx, store); err != nil {\n    if strings.Contains(err.Error(), \"authentication not configured\") {\n        fmt.Fprintln(os.Stderr, \"Run: bd config set linear.api_key <key>  (or export LINEAR_API_KEY)\")\n        os.Exit(2)\n    }\n    return err\n}","preventionTips":["Store the API key persistently: bd config set linear.api_key (kept in config.yaml, not the pushed DB)","In CI, inject LINEAR_OAUTH_CLIENT_ID/SECRET or LINEAR_API_KEY as secrets","Double-check env var spelling (LINEAR_API_KEY, not LINEAR_APIKEY/TOKEN)","Run bd from the workspace whose config.yaml actually contains the key"],"tags":["configuration","authentication","linear","env-var"],"backgroundTag":"missing-credentials","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}