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_seconds

View on GitHub (pinned to 3810898a74)

Solutions

  1. 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)
  2. For services/containers, add the variable to the unit file, compose file, or CI secrets so the goose process sees it
  3. Check the api_key_env spelling in providers.yaml matches the variable you actually set
  4. 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

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


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/06d98c44553676d2. Report an issue: GitHub.