Hmbown/CodeWhale · error
custom providers store base_url in their named
Error message
custom providers store base_url in their named [providers.<name>] table
What it means
Custom providers live in a user-chosen [providers.<name>] table, so there is no fixed key for ApiProvider::Custom in provider_base_url_table_key. Persisting a base_url for a custom provider through this static-key path is out of scope (the #1519 constrained slice); the function bails to prevent writing to a wrong/generic key.
Solutions
- Use persist_custom_provider instead, which writes the named [providers.<name>] table.
- Edit the [providers.<name>] table in the config file directly.
Example fix
// before persist_provider_base_url_key(config_path, ApiProvider::Custom, &url)?; // after persist_custom_provider(config_path, name, &url, None, None, None)?;
Defensive patterns
Strategy: validation
Validate before calling
if matches!(provider, ApiProvider::Custom) { persist_custom_provider(path, name, &url, None, None, None)?; } else { persist_provider_base_url_key(path, provider, &url)?; } Type guard
fn is_custom(p: ApiProvider) -> bool { matches!(p, ApiProvider::Custom) } Try / catch
if let Err(e) = persist_provider_base_url_key(path, provider, &url) {
if e.to_string().contains("custom providers") {
persist_custom_provider(path, &name, &url, None, None, None)?;
} else { return Err(e); }
} Prevention
- Use persist_custom_provider for ApiProvider::Custom.
- Remember custom providers have no fixed config key.
- Edit [providers.<name>] tables directly when scripting.
When it happens
Trigger: Calling persist_provider_base_url_key with ApiProvider::Custom to save a base_url for a custom provider.
Common situations: A script or UI tries to save a custom provider's base_url via the same helper used for built-in providers.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- custom provider ' ' must set [providers. ].kind =…
- advisor model ` ` resolved only to a custom provider kind…
- Antigravity is a retired, non-runnable legacy provider…
- Antigravity is a retired, non-runnable legacy provider…
- Cannot resume agent on its saved provider
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/aabeaea6d6d271e3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config_persistence.rs:632
ApiProvider::Mistral => Ok("mistral"),
ApiProvider::Google => Ok("google"),
ApiProvider::Antigravity => Ok("antigravity"),
ApiProvider::Telecomjs => Ok("telecomjs"),
ApiProvider::Edenai => Ok("edenai"),
ApiProvider::Zenmux => Ok("zenmux"),
ApiProvider::Csdn => Ok("csdn"),
ApiProvider::Concentrate => Ok("concentrate"),
ApiProvider::Codewhale => Ok("codewhale"),
ApiProvider::ModelstudioTokenPlan => Ok("modelstudio_token_plan"),
ApiProvider::ModelstudioTokenPlanAnthropic => Ok("modelstudio_token_plan_anthropic"),
ApiProvider::ModelstudioCodingPlan => Ok("modelstudio_coding_plan"),
ApiProvider::ModelstudioCodingPlanAnthropic => Ok("modelstudio_coding_plan_anthropic"),
// Custom providers live under a user-chosen `[providers.<name>]` table,
// not a fixed key. Persisting base_url through this static-key path is
// out of scope for the #1519 constrained slice; users edit the named
// table directly.
ApiProvider::Custom => {
anyhow::bail!("custom providers store base_url in their named [providers.<name>] table")
}
}
}
pub(crate) fn persist_custom_provider(
config_path: Option<&Path>,
provider_id: &str,
base_url: &str,
model: Option<&str>,
api_key_env: Option<&str>,
) -> anyhow::Result<PathBuf> {
let provider_id = normalize_custom_provider_id(provider_id)?;
let base_url = normalize_custom_provider_base_url(base_url)?;
let model = model.and_then(normalize_optional_custom_provider_field);
let api_key_env = api_key_env.and_then(normalize_optional_custom_provider_field);
let path = config_toml_path(config_path)?;
mutate_config_document(&path, |doc| {View on GitHub (pinned to 73e0f67d83)