Hmbown/CodeWhale · error

resolved a different provider

Error message

resolved a different provider

What it means

resolve_api_key resolves runtime options for a specific provider and asserts the resolution still selects that provider. If resolve_runtime_options_with_secrets returns a different provider (config routing/overrides redirected the slot), the result would be a key for the wrong provider, so the handoff refuses with this error.

Solutions

  1. Fix the config so the requested provider is actually selected: remove/adjust conflicting model_alias or provider overrides for the invoked route.
  2. Pass explicit runtime overrides on the command so resolution cannot be redirected (the code scopes overrides per provider via runtime_overrides_for_provider).
  3. Run the resolution/diagnostic command to print which provider the config resolves to, then request the API key for that provider.

Example fix

// before (config.toml)
[providers]
default = "openrouter"  # redirects the xai request
// after
codewhale config set providers.default xai
codewhale credential api-key xai
Defensive patterns

Strategy: validation

Validate before calling

let resolved = store.config.resolve_runtime_options_with_secrets(
    &runtime_overrides_for_provider(&overrides, provider), &secrets);
if resolved.provider != provider {
    eprintln!("config routes this request to {:?}, not {:?}", resolved.provider, provider);
}

Type guard

fn resolves_to(provider: ProviderKind, resolved: &ResolvedOptions) -> bool { resolved.provider == provider }

Try / catch

match resolve_api_key(&store, &overrides, provider) {
    Err(e) if e.to_string() == "resolved a different provider" => {
        eprintln!("fix model_alias/provider overrides so the requested provider is selected");
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling the credential handoff (api_key subcommand) with a provider argument while the config's routing table / model aliases / runtime overrides resolve that request to a different ProviderKind — e.g. a default-provider or alias override masks the requested provider.

Common situations: A model_alias or provider override in config.toml routes requests to another provider; ambient config edited after the CLI arg was chosen; requesting `api_key xai` while config defaults to openrouter, etc.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at crates/cli/src/credential_handoff.rs:35

    // SAFETY: this one-shot CLI exits before another command can inherit it.
    unsafe {
        let _ = libc::signal(libc::SIGPIPE, libc::SIG_IGN);
    }
    Ok(())
}

pub(crate) fn resolve_api_key(
    store: &ConfigStore,
    secrets: &Secrets,
    provider: ProviderKind,
    runtime_overrides: &CliRuntimeOverrides,
) -> Result<String> {
    let resolved = store.config.resolve_runtime_options_with_secrets(
        &runtime_overrides_for_provider(runtime_overrides, provider),
        secrets,
    );
    if resolved.provider != provider {
        bail!("resolved a different provider");
    }
    let source = resolved.api_key_source;
    if source != Some(RuntimeApiKeySource::Cli) {
        if provider == ProviderKind::OpenaiCodex {
            bail!("bearer credentials are not an API key");
        }
        let uses_api_key = provider != ProviderKind::Xai
            || xai_auth_diagnostics(store, runtime_overrides).evaluates_runtime_api_key();
        ensure!(uses_api_key, "OAuth bearer credentials are not an API key");
        let kimi_bearer = provider == ProviderKind::Moonshot
            && resolved
                .auth_mode
                .as_deref()
                .is_some_and(auth_mode_uses_kimi_imported_token);
        ensure!(!kimi_bearer, "bearer credentials are not an API key");
    }
    ensure!(source.is_some(), "no runtime-effective API key");
    resolved

View on GitHub (pinned to 73e0f67d83)