{"record":{"id":"e6a7983ab5e1f497","repo":"aaif-goose/goose","slug":"missing-required-key-e6a798","errorCode":null,"errorMessage":"missing required key {}: {}","messagePattern":"missing required key (.+?): (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/goose-providers/src/ollama.rs","lineNumber":323,"sourceCode":"    let mut base_url = Url::parse(&base)\n        .map_err(|e| anyhow::anyhow!(\"Invalid base URL '{}': {}\", config.base_url, e))?;\n\n    let is_localhost = matches!(base_url.host_str(), Some(\"localhost\" | \"127.0.0.1\" | \"::1\"));\n\n    if base_url.port().is_none() && !base_has_scheme && is_localhost {\n        base_url\n            .set_port(Some(OLLAMA_DEFAULT_PORT))\n            .map_err(|_| anyhow::anyhow!(\"Failed to set default port\"))?;\n    }\n\n    let api_key = if config.api_key_env.is_empty() {\n        None\n    } else {\n        match key_resolver.resolve_key(config.api_key_env.as_str()) {\n            Ok(key) => Some(key),\n            Err(err) => {\n                if config.requires_auth {\n                    anyhow::bail!(\"missing required key {}: {}\", config.api_key_env, err);\n                }\n                None\n            }\n        }\n    };\n\n    let auth = match api_key {\n        Some(key) if !key.is_empty() => AuthMethod::BearerToken(key),\n        _ => AuthMethod::NoAuth,\n    };\n\n    let mut api_client =\n        ApiClient::with_timeout_and_tls(base_url.to_string(), auth, timeout, tls_config)?;\n\n    if let Some(headers) = &config.headers {\n        let mut header_map = reqwest::header::HeaderMap::new();\n        for (key, value) in headers {\n            let header_name = reqwest::header::HeaderName::from_bytes(key.as_bytes())?;","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-providers/src/ollama.rs#L305-L341","documentation":"The Ollama declarative config names an api key environment variable via api_key_env, and the key resolver (which reads that env var) failed while the config also sets requires_auth: true — so the missing key is fatal instead of being ignored. The message names both the env var and the underlying resolver error. If requires_auth were false (or unset), a failing resolve would just mean no auth header, which suits local Ollama servers that don't check keys.","triggerScenarios":"A declarative Ollama provider JSON with \"api_key_env\": \"OLLAMA_API_KEY\" (any name) and \"requires_auth\": true, run where that environment variable is not set — e.g. routing through an auth-gating proxy (LiteLLM, corporate gateway) in CI that lacks the secret.","commonSituations":"Teams front Ollama with an authenticating proxy and forget the secret in CI/service environments; the env var name in JSON has a typo or case mismatch versus what's exported; local setups copied a remote team's config but don't run the proxy, so the var was never needed before.","solutions":["Export the named variable in goose's environment: export OLLAMA_API_KEY=... (match the name in api_key_env exactly, case included)","For a local Ollama with no auth in front, set \"requires_auth\": false so a missing key is tolerated","If a proxy is optional, prefer requires_auth: false and supply the key only when present","Double-check api_key_env spelling — a var that never exists will always fail when required"],"exampleFix":"// before\n{ \"name\": \"proxied-ollama\", \"engine\": \"ollama\", \"base_url\": \"https://llm.internal:11434\",\n  \"api_key_env\": \"OLLAMA_API_KEY\", \"requires_auth\": true }\n// OLLAMA_API_KEY not exported -> missing required key OLLAMA_API_KEY\n\n// after\nexport OLLAMA_API_KEY=sk-...   # or, for plain local servers:\n// \"requires_auth\": false","handlingStrategy":"validation","validationCode":"fn ollama_auth_satisfiable(api_key_env: &str, requires_auth: bool) -> anyhow::Result<()> {\n    if requires_auth && !api_key_env.is_empty() && std::env::var(api_key_env).is_err() {\n        anyhow::bail!(\"export {api_key_env} (required by this provider) or set requires_auth=false\");\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"// Pre-flight all required key env vars once at startup and list them together:\nlet missing: Vec<_> = providers.iter()\n    .filter(|p| p.requires_auth && std::env::var(&p.api_key_env).is_err())\n    .map(|p| p.api_key_env.clone()).collect();\nanyhow::ensure!(missing.is_empty(), \"missing required API key env vars: {}\", missing.join(\", \"));","preventionTips":["Set requires_auth:true only for endpoints that actually verify a key; local Ollama doesn't","Wire secrets through environment injection (dotenv, systemd, k8s) and verify with a pre-flight check","Keep api_key_env names in provider JSON aligned with the names your secret store injects (case-sensitive)"],"tags":["ollama","env-vars","authentication","json-config"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}