Hmbown/CodeWhale · error · anyhow::Error
custom provider base URL is invalid
Error message
custom provider base URL is invalid: {err} What it means
normalize_custom_provider_base_url validates the base URL supplied for a custom provider. A URL that reqwest::Url::parse rejects (bad scheme, missing host, malformed characters) produces this error before persist_custom_provider writes anything.
Solutions
- Include an explicit http:// or https:// scheme, e.g. http://localhost:11434/v1.
- Remove trailing slashes, spaces, or invisible characters from the URL.
- Verify the URL has a host (IP or domain); a bare path or empty value is rejected.
Example fix
// before
let url = normalize_custom_provider_base_url("localhost:8080/v1")?;
// after
let url = normalize_custom_provider_base_url("http://localhost:8080/v1")?; Defensive patterns
Strategy: validation
Validate before calling
fn valid_custom_base_url(raw: &str) -> bool {
let v = raw.trim().trim_end_matches('/');
!v.is_empty()
&& reqwest::Url::parse(v).map(|u| matches!(u.scheme(), "http" | "https") && u.host_str().is_some()).unwrap_or(false)
} Try / catch
match normalize_custom_provider_base_url(input) {
Err(e) => eprintln!("fix base URL (need http(s) + host): {e}"),
Ok(url) => persist_custom_provider(&url, ...)?,
} Prevention
- Always include an explicit http:// or https:// scheme.
- Trim trailing slashes and whitespace before submitting.
- Test the URL by opening it in a browser or curl before saving.
When it happens
Trigger: persist_custom_provider is called with a base URL string that fails reqwest's URL parsing — e.g. 'myserver:8080/v1' (no scheme), 'http//x', or a URL containing control characters.
Common situations: Typing an endpoint without http:// or https://; pasting a URL with embedded whitespace or invisible characters; entering 'localhost:11434' without a scheme; trailing slashes are tolerated but a missing host is not.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- custom provider base URL is required
- custom provider base URL must be an http(s) URL with a host
- custom provider ' ' must set [providers. ].kind =…
- outbound origin is empty or oversized
- Refusing invalid base URL
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/5c395107eb9014cb.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config_persistence.rs:715
}
if !value
.chars()
.all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '_' | '-'))
{
bail!("custom provider name may only use letters, numbers, '-' and '_'");
}
Ok(value.to_string())
}
fn normalize_custom_provider_base_url(raw: &str) -> anyhow::Result<String> {
use anyhow::bail;
let value = raw.trim().trim_end_matches('/');
if value.is_empty() {
bail!("custom provider base URL is required");
}
let parsed = reqwest::Url::parse(value)
.map_err(|err| anyhow::anyhow!("custom provider base URL is invalid: {err}"))?;
if !matches!(parsed.scheme(), "http" | "https") || parsed.host_str().is_none() {
bail!("custom provider base URL must be an http(s) URL with a host");
}
Ok(value.to_string())
}
fn normalize_optional_custom_provider_field(raw: &str) -> Option<String> {
let value = raw.trim();
(!value.is_empty()).then(|| value.to_string())
}
pub(crate) fn persist_hotbar_bindings(
config_path: Option<&Path>,
bindings: &[codewhale_config::HotbarBindingToml],
) -> anyhow::Result<PathBuf> {
let path = config_toml_path(config_path)?;
mutate_config_document(&path, |doc| {
let table = doc.as_table_mut();View on GitHub (pinned to 73e0f67d83)