Hmbown/CodeWhale · error

Custom endpoint credentials for

Error message

Custom endpoint credentials for {route_name} must be bound explicitly. Ambient provider credentials are not sent to {}. Add api_key or api_key_env to this provider route, or pass --api-key with --base-url.

What it means

Custom (--base-url / custom endpoint) provider routes must carry their own explicit credentials. Codewhale will not forward ambient provider credentials (keys meant for the official provider endpoint) to a user-supplied custom base URL, so the route fails at config resolution before any request leaves the machine.

Solutions

  1. Add api_key = "..." to the [providers.<route_name>] table in ~/.codewhale/config.toml.
  2. Or add api_key_env = "YOUR_ENV_VAR" to the route and export that variable.
  3. Or pass --api-key together with --base-url on the command line.

Example fix

// before
[providers.my-proxy]
base_url = "https://internal.corp/v1"

// after
[providers.my-proxy]
base_url = "https://internal.corp/v1"
api_key_env = "MY_PROXY_KEY"
Defensive patterns

Strategy: validation

Validate before calling

fn custom_endpoint_has_creds(p: &ProviderCfg) -> Result<(), String> {
    if p.base_url.is_some() && p.api_key.is_none() && p.api_key_env.is_none() {
        Err(format!("provider '{}' has a custom base_url but no api_key/api_key_env", p.name))
    } else { Ok(()) }
}

Try / catch

match result {
    Err(e) if e.to_string().contains("must be bound explicitly") => {
        eprintln!("add api_key or api_key_env to this route, or pass --api-key with --base-url");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A provider route is marked custom_endpoint (custom base URL via [providers.<name>] base_url or --base-url) while its config has neither api_key nor api_key_env and no --api-key was passed.

Common situations: Pointing an OpenAI-compatible proxy/gateway at codewhale but forgetting to attach the proxy's key; moving a working official-provider config onto a self-hosted relay and assuming the existing ambient key still applies.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/649cf5e0d257f159. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/config.rs:7313

        // The Codewhale API always authenticates. It is not a self-hosted
        // runtime, and a loopback `CODEWHALE_API_BASE` is a test origin for
        // the same authenticated contract — never a keyless one. Without this
        // the loopback arm below returned an empty key and the request went
        // out with no `Authorization` header at all.
        if provider != ApiProvider::Codewhale
            && !auth_mode_requires_api_key(auth_mode.as_deref())
            && (provider_route_is_keyless_self_hosted(provider, &self.active_route_base_url())
                || base_url_uses_local_host(&self.active_route_base_url()))
        {
            return Ok(String::new());
        }

        if custom_endpoint {
            let route_name = self
                .provider
                .as_deref()
                .unwrap_or_else(|| provider.as_str());
            anyhow::bail!(
                "Custom endpoint credentials for {route_name} must be bound explicitly. Ambient provider credentials are not sent to {}. Add api_key or api_key_env to this provider route, or pass --api-key with --base-url.",
                self.active_route_base_url()
            );
        }

        match provider {
            ApiProvider::Codewhale => anyhow::bail!(
                "Codewhale API key not found, so no request was sent.\n\
                 \n\
                 The Codewhale API authenticates every model with one account \
                 API key carrying the `models:infer` scope.\n\
                 \n\
                 1. Create one and save it on this machine:\n\
                        codewhale account api-keys create --name <name> --scope models:infer --use\n\
                 2. Or export it for this shell:\n\
                        export CODEWHALE_API_KEY=cwc_key_...\n\
                 \n\
                 You can also create a key at {} and put it in \

View on GitHub (pinned to 73e0f67d83)