Hmbown/CodeWhale · error · anyhow::Error

Custom endpoint credentials for {route_name} must be bound e

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

When a custom endpoint (base_url override) is used on a non-loopback host and the route is not keyless-self-hosted, key resolution refuses to fall through: ambient provider credentials are intentionally never sent to a custom host. The route must bind its own api_key/api_key_env, or the caller must pass --api-key alongside --base-url.

Source

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

                        "antigravity credential plane did not yield a sendable token"
                    );
                }
            }
        }

        if !auth_mode_requires_api_key(auth_mode.as_deref())
            && (provider_route_is_keyless_self_hosted(provider, &self.deepseek_base_url())
                || base_url_uses_local_host(&self.deepseek_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.deepseek_base_url()
            );
        }

        match provider {
            ApiProvider::Deepseek | ApiProvider::DeepseekCN => anyhow::bail!(
                "DeepSeek API key not found.\n\
                 \n\
                 1. Get a key:  https://platform.deepseek.com/api_keys\n\
                 2. Save it (works in every folder, no OS prompts):\n\
                        codewhale auth set --provider deepseek\n\
                 \n\
                 Alternatives:\n\
                   • export DEEPSEEK_API_KEY=<your-key>      (current shell only;\n\
                     also note: zsh users — exports in ~/.zshrc only reach interactive\n\
                     shells, prefer ~/.zshenv for everything)\n\
                   • api_key = \"<your-key>\"  in ~/.codewhale/config.toml\n\

View on GitHub (pinned to 8880682c63)

Solutions

  1. Add api_key or api_key_env to the [providers.<route>] table for that custom route.
  2. Pass --api-key together with --base-url on the command line.
  3. If the endpoint truly needs no auth, host it on a loopback address so the keyless self-hosted path applies.

Example fix

# before
codewhale --provider myroute --base-url https://api.example.com/v1

# after
codewhale --provider myroute --base-url https://api.example.com/v1 --api-key sk-...
# or in config:
# [providers.myroute]
# base_url = "https://api.example.com/v1"
# api_key = "sk-..."
Defensive patterns

Strategy: validation

Validate before calling

// preflight: a custom endpoint on a non-loopback host must carry explicit credentials
fn custom_endpoint_credentials_bound(cfg: &Config, route: &ProviderConfig) -> bool {
    route.api_key.is_some()
        || route.api_key_env.is_some()
        || base_url_uses_local_host(&cfg.deepseek_base_url())
}

anyhow::ensure!(
    custom_endpoint_credentials_bound(&config, route),
    "custom endpoint needs api_key/api_key_env or --api-key"
);

Type guard

fn custom_route_needs_key(base_url: &str) -> bool {
    !base_url_uses_local_host(&base_url.to_string())
}

Try / catch

if let Err(e) = config.deepseek_api_key() {
    if e.to_string().starts_with("Custom endpoint credentials for") {
        // prompt for --api-key or an [providers.<route>] api_key entry; never forward ambient creds
        return Err(e);
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Launching with --base-url https://api.example.com/v1 without --api-key while [providers.<route>] has neither api_key nor api_key_env; pointing a custom route at a remote gateway expecting the ambient ANTHROPIC/DEEPSEEK key to be reused.

Common situations: Migrating from a first-party provider to an OpenAI-compatible gateway and assuming env credentials carry over; typos in base_url turning a loopback plan into a remote one; proxy front-ends that require their own keys.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/649cf5e0d257f159. Report an issue: GitHub.