aaif-goose/goose · error
missing required key {}: {}
Error message
missing required key {}: {} What it means
While constructing the Anthropic provider, goose resolves the API key through a key resolver using the env var named by the provider's api_key_env (for the built-in anthropic provider this is ANTHROPIC_API_KEY). If resolution fails and the config is marked requires_auth, provider construction bails with 'missing required key {ENV}: {cause}' instead of silently continuing unauthenticated.
Source
Thrown at crates/goose-providers/src/anthropic.rs:414
None
};
if config.dynamic_models == Some(false) && custom_models.is_none() {
return Err(anyhow::anyhow!(
"Provider '{}' has dynamic_models: false but no static models listed; \
at least one entry in `models` is required.",
config.name
));
}
let api_key = if config.api_key_env.is_empty() {
None
} else {
match key_resolver.resolve_key(config.api_key_env.as_str()) {
Ok(key) => Some(key),
Err(err) => {
if config.requires_auth {
anyhow::bail!("missing required key {}: {}", config.api_key_env, err);
}
None
}
}
};
let auth = match api_key {
Some(key) if !key.is_empty() => AuthMethod::ApiKey {
header_name: "x-api-key".to_string(),
key,
},
_ => AuthMethod::NoAuth,
};
let format_options = format_options_for_provider(config.preserves_thinking);
let timeout_secs = config
.timeout_secondsView on GitHub (pinned to 3810898a74)
Solutions
- Export the key in the environment goose runs in: export ANTHROPIC_API_KEY=sk-ant-... (or the custom api_key_env name from the config)
- For services/containers, add the variable to the unit file, compose file, or CI secrets so the goose process sees it
- Check the api_key_env spelling in providers.yaml matches the variable you actually set
- Only if the endpoint truly needs no auth (local gateway), set requires_auth: false on that provider entry
Example fix
# before (shell) $ goose session Error: missing required key ANTHROPIC_API_KEY: environment variable not found # after $ export ANTHROPIC_API_KEY="sk-ant-..." $ goose session
Defensive patterns
Strategy: validation
Validate before calling
let env_name = &cfg.api_key_env; // e.g. ANTHROPIC_API_KEY
if cfg.requires_auth {
let present = std::env::var(env_name).map(|v| !v.trim().is_empty()).unwrap_or(false);
anyhow::ensure!(present, "set {env_name} before starting goose");
} Prevention
- Set required key env vars in the exact launcher context (shell profile, systemd Environment=, container env, CI secrets)
- Double-check api_key_env spelling against the variable you export
- Add a startup preflight that checks required_auth providers have resolvable keys
- For local no-auth gateways, set requires_auth: false deliberately rather than exporting dummy keys
When it happens
Trigger: Starting goose (or first use of the provider) with the named environment variable unset, empty, or unreadable in the process environment, while requires_auth is true (default for the hosted Anthropic API). resolve_key returns Err and the bail fires immediately.
Common situations: ANTHROPIC_API_KEY not exported in the shell/daemon environment (systemd unit, cron, container missing env); typo in a custom api_key_env value; key stored in a launcher script but goose launched from another context; CI runners without secrets injected.
Related errors
- Provider '{}' has dynamic_models: false but no static models
- Anthropic provider does not support non-streaming mode. All
- GOOSE_SERVER__SECRET_KEY must be set when using GOOSE_EXTERN
- Failed to spawn goose-cli main thread: {}
- goose-cli main thread panicked
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/06d98c44553676d2.
Report an issue: GitHub.