gastownhall/beads · error · errAPIKeyRequired
%w: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key in
Error message
%w: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key in config
What it means
newHaikuClient requires an AI API key to construct the Anthropic (or MiniMax-compatible) client. It resolves the key via config.ResolveAIAPIKey with the order: explicit apiKey parameter > ANTHROPIC_API_KEY env > MINIMAX_API_KEY env > ai.api_key config. If all are empty it returns errAPIKeyRequired wrapped with this message — the compaction feature simply cannot authenticate without a key.
Source
Thrown at internal/compact/haiku.go:51
// haikuClient wraps the Anthropic API for issue summarization.
type haikuClient struct {
client anthropic.Client
model anthropic.Model
apiKeySource config.AIAPIKeySource
baseURL string
tier1Template *template.Template
maxRetries int
initialBackoff time.Duration
auditEnabled bool
auditActor string
}
// newHaikuClient creates a new Haiku API client.
// API key resolution order: ANTHROPIC_API_KEY env var > MINIMAX_API_KEY env var > ai.api_key config > explicit apiKey parameter.
func newHaikuClient(apiKey string) (*haikuClient, error) {
apiKey, keySource := config.ResolveAIAPIKey(apiKey)
if apiKey == "" {
return nil, fmt.Errorf("%w: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key in config", errAPIKeyRequired)
}
clientOptions := []option.RequestOption{option.WithAPIKey(apiKey)}
baseURL := config.DefaultAIBaseURL(keySource)
if baseURL != "" {
clientOptions = append(clientOptions, option.WithBaseURL(baseURL))
}
client := anthropic.NewClient(clientOptions...)
tier1Tmpl, err := template.New("tier1").Parse(tier1PromptTemplate)
if err != nil {
return nil, fmt.Errorf("failed to parse tier1 template: %w", err)
}
aiMetricsOnce.Do(initAIMetrics)
return &haikuClient{View on GitHub (pinned to 71377f2769)
Solutions
- export ANTHROPIC_API_KEY="sk-ant-..." in your shell or CI environment before running bd
- Set MINIMAX_API_KEY instead if you use MiniMax as the provider
- Add ai.api_key to the bd config file for a persistent, per-repo setting
- Verify resolution order if multiple sources are set — explicit parameter wins, then ANTHROPIC_API_KEY overrides MINIMAX_API_KEY
- Check that your service runner (cron/systemd/CI) actually loads the env file
Example fix
// before (key missing)
client, err := compact.New("") // -> errAPIKeyRequired
// after
os.Setenv("ANTHROPIC_API_KEY", os.Getenv("ANTHROPIC_API_KEY")) // ensure exported
client, err := compact.New("") // env var picked up
// or pass explicitly:
client, err := compact.New("sk-ant-...") Defensive patterns
Strategy: validation
Validate before calling
// check key availability before constructing the client
if os.Getenv("ANTHROPIC_API_KEY") == "" && os.Getenv("MINIMAX_API_KEY") == "" {
if cfg.AI.APIKey == "" {
return errors.New("no AI API key: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key")
}
}
client, err := compact.New("") Try / catch
client, err := compact.New(apiKey)
if errors.Is(err, compact.ErrAPIKeyRequired) {
return fmt.Errorf("configure an AI key: %w", err)
} Prevention
- Export ANTHROPIC_API_KEY in shell profiles, CI secrets, and service units
- Set ai.api_key in bd config for environments that don't inherit env vars
- Never rename the env var (ANTHROPIC_APIKEY is not read)
- Remember precedence: explicit param > ANTHROPIC_API_KEY > MINIMAX_API_KEY > config
When it happens
Trigger: Calling New (compact client constructor) when no ANTHROPIC_API_KEY or MINIMAX_API_KEY environment variable is set and ai.api_key is absent/empty in the bd config file.
Common situations: Fresh clone or CI environment where the env var was never exported; running `bd compact` under systemd/cron that does not inherit your shell profile; typos like ANTHROPIC_APIKEY; key defined in the wrong config file; key expired and removed.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- audit JSONL sidecar is disabled; set audit.enabled=true or B
- failed to create Haiku client: %w
- multiple .doltcfg directories detected
- dolt directory is required
- httpapi: a configured role fires this workspace's hooks; thi
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cc69b2633d2ac5fb.
Report an issue: GitHub.