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
- Add kind = "openai-compatible" under [providers.<id>] and set base_url/model
- If you meant a built-in provider, use its canonical id instead of a custom table
- 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
- Always create custom providers via `config set providers.<id>.kind openai-compatible` first
- Include the kind line in any copy-paste provider template
- Validate config.toml loads after hand edits
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
- context_window must be greater than 0
- provider auth source command must include at least one non-e
- provider auth source secret must include secret_id
- unknown field '{field_key}' for built-in provider '{provider
- unknown field '{field_key}' for custom provider '{provider_i
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/e2634c8a5dd9ff80.
Report an issue: GitHub.