Hmbown/CodeWhale · error

custom provider ' ' must set [providers. ].kind =…

Error message

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

What it means

Thrown when validating a custom provider table: every entry under `[providers.<id>]` must declare `kind = "openai-compatible"` (case-insensitive; underscores allowed for hyphens). A custom provider without this exact kind marker cannot be constructed as a table, because the library only knows how to build OpenAI-compatible custom providers.

Solutions

  1. Add `kind = "openai-compatible"` inside the `[providers.<provider_id>]` table.
  2. Correct the `kind` value to exactly "openai-compatible" (case/underscore-insensitive).
  3. If the provider needs a non-OpenAI protocol, do not register it as a custom provider; use a built-in provider kind instead.

Example fix

// before
[providers.my_llm]
base_url = "http://localhost:8080/v1"
// after
[providers.my_llm]
kind = "openai-compatible"
base_url = "http://localhost:8080/v1"
Defensive patterns

Strategy: validation

Validate before calling

fn custom_provider_table_valid(t: &toml::Table) -> bool {
    t.get("kind")
        .and_then(|k| k.as_str())
        .map(|k| k.trim().to_ascii_lowercase().replace('_', "-") == "openai-compatible")
        .unwrap_or(false)
}

Try / catch

match load_config() {
    Err(e) if e.to_string().contains("openai-compatible") => {
        eprintln!("{e}");
        // add kind = "openai-compatible" to the offending [providers.<id>] table
    }
    other => other,
}

Prevention

When it happens

Trigger: Defining a custom provider in config.toml whose `[providers.<provider_id>]` table is missing the `kind` key, or sets it to something other than "openai-compatible" (e.g. "anthropic", "ollama", or an empty value) — checked via the table validation reached from config loading/custom-provider construction.

Common situations: User adds a custom provider section and forgets `kind`; copies a provider block from docs for a native provider and pastes it as a custom entry; typo like `kind = "openai_compatible"` with the wrong separator is fine (normalized), but `kind = "custom"` fails.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

            .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 73e0f67d83)