Hmbown/CodeWhale · error
base URL cannot be empty
Error message
base URL cannot be empty
What it means
save_provider_base_url_for_identity trims and slash-trims the guided-setup endpoint and rejects an empty value; a provider's [providers.<name>] base_url must be a non-empty URL, and the narrow writer never touches the root base_url.
Solutions
- Pass a complete base URL (e.g. `https://api.example.com/v1`) to the routine
- Validate the URL is non-empty and parses before calling save
- To return to a provider's default endpoint, remove the override instead of saving an empty value
Example fix
// before save_provider_base_url_for_identity(&identity, &cfg, "")?; // after let url = input.trim(); anyhow::ensure!(!url.is_empty(), "base URL required"); save_provider_base_url_for_identity(&identity, &cfg, url)?;
Defensive patterns
Strategy: validation
Validate before calling
let url = base_url.trim();
if url.is_empty() { return Err(anyhow::anyhow!("base URL required")); } Try / catch
if let Err(e) = save_provider_base_url_for_identity(&identity, &cfg, u) {
if e.to_string().contains("base URL cannot be empty") {
// clear the override via the delete path instead
}
} Prevention
- Validate URLs parse (e.g. `url::Url::parse`) before saving
- Treat clearing the field as 'remove override', not save-empty
- Pre-fill the provider's default endpoint in forms
When it happens
Trigger: Calling `save_provider_base_url_for_identity` with `base_url` empty or whitespace-only after trim.
Common situations: User cleared the base-URL field and saved; migration imported a config with an empty URL; script variable unset before the call.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- browser URL cannot be empty
- classifier-approved read command was empty
- Codewhale runtime event file is empty.
- CRON field must not be empty
- custom provider id cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/db453acc2c12bdb8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config.rs:12724
identity.provider,
identity.persisted_id().unwrap_or(&identity.key),
model,
)
}
/// Persist a guided-setup endpoint choice into the provider's own
/// `[providers.<name>] base_url` (#4526).
///
/// Deliberately narrow: it never touches the root `base_url`, another
/// provider's table, or any other key, so a billing-route choice cannot
/// repoint an unrelated route.
pub(crate) fn save_provider_base_url_for_identity(
identity: &ProviderIdentity,
_route_config: &Config,
base_url: &str,
) -> Result<PathBuf> {
let base_url = base_url.trim();
anyhow::ensure!(!base_url.is_empty(), "base URL cannot be empty");
let config_path = try_default_config_path()
.context("Failed to resolve config path for provider base URL.")?;
ensure_parent_dir(&config_path)?;
let key_inside = if identity.provider == ApiProvider::Custom {
let key = identity.key.trim();
anyhow::ensure!(!key.is_empty(), "custom provider id cannot be empty");
key
} else {
provider_config_key(identity.provider).context("provider base URL table")?
};
crate::config_persistence::mutate_config_document(&config_path, |doc| {
crate::config_persistence::set_document_value(
doc,
&["providers", key_inside, "base_url"],
base_url,
)
})
.with_context(|| format!("Failed to write config to {}", config_path.display()))?;View on GitHub (pinned to 73e0f67d83)