Hmbown/CodeWhale · error · anyhow::Error

custom provider '{provider_id}' must set [providers.{provide

Error message

custom provider '{provider_id}' must set [providers.{provider_id}].kind = "openai-compatible"

What it means

named_custom_provider_table (crates/config/src/lib.rs:2629) requires every named custom provider table to declare kind = "openai-compatible". The check is lenient about case and underscores (trimmed, lowercased, '_' -> '-' before comparing), but the key must be present and match. Custom providers ride the OpenAI-compatible wire, so an untyped table cannot be loaded.

Source

Thrown at crates/config/src/lib.rs:2629

            .extras
            .get(provider_id)
            .and_then(toml::Value::as_table)
            .with_context(|| {
                format!(
                    "custom provider '{provider_id}' requires a matching [providers.{provider_id}] table"
                )
            })?;
        let compatible = table
            .get("kind")
            .and_then(toml::Value::as_str)
            .is_some_and(|kind| {
                kind.trim()
                    .to_ascii_lowercase()
                    .replace('_', "-")
                    .eq("openai-compatible")
            });
        if !compatible {
            bail!(
                "custom provider '{provider_id}' must set [providers.{provider_id}].kind = \"openai-compatible\""
            );
        }
        Ok(table)
    }

    fn named_custom_provider_config(&self) -> Option<ProviderConfigToml> {
        let provider_id = self.named_custom_provider_id()?;
        self.named_custom_provider_table(provider_id).ok()?;
        self.providers
            .extras
            .get(provider_id)
            .cloned()?
            .try_into()
            .ok()
    }

    /// Mutable access to a custom provider's `[providers.<id>]` table,

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Add kind = "openai-compatible" under [providers.<id>] and set base_url/model
  2. If you meant a built-in provider, use its canonical id instead of a custom table
  3. Use `config set providers.<id>.kind openai-compatible` instead of hand-editing so the value is normalized for you

Example fix

# before
[providers.local]
base_url = "http://localhost:8080/v1"
model = "llama3"

# after
[providers.local]
kind = "openai-compatible"
base_url = "http://localhost:8080/v1"
model = "llama3"
Defensive patterns

Strategy: validation

Validate before calling

fn is_openai_compatible_kind(kind: &str) -> bool {
    kind.trim().to_ascii_lowercase().replace('_', "-") == "openai-compatible"
}
assert!(is_openai_compatible_kind(kind)); // before writing the provider table

Type guard

fn valid_custom_provider_table(t: &toml::Value) -> bool {
    t.get("kind").and_then(toml::Value::as_str).is_some_and(|k| k.trim().to_ascii_lowercase().replace('_', "-") == "openai-compatible")
}

Try / catch

match load_named_custom_provider() {
    Ok(cfg) => { /* use */ }
    Err(e) if e.to_string().contains("kind = \"openai-compatible\"") => { /* add the kind key, retry */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Adding [providers.myprov] to config.toml without a kind key, setting kind to another value (e.g. "anthropic", "openai"), or misspelling the value so the normalized comparison fails.

Common situations: Hand-editing config.toml to add a self-hosted/local model gateway (llama.cpp, vllm, Ollama OpenAI endpoint), copying a built-in provider block as a template and forgetting the kind field.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/e2634c8a5dd9ff80. Report an issue: GitHub.