ducaale/xh · error
couldn't extract host from url
Error message
couldn't extract host from url
What it means
When loading a named session, xh derives the session filename from the request URL's host (and optional port). If the Url has no host, or the host is '.' or '..', no usable filename can be formed, so path_from_url errors and load_session aborts.
Solutions
- Include scheme and host in the URL, e.g. https://api.example.com instead of a relative path
- Validate the URL parses to a Some(host) before invoking with --session
- Fix environment/variable substitution that leaves the host empty or '.'
- If connecting to localhost, use http://localhost:8080 explicitly
Example fix
// before xh --session=mysess GET :8080/api/items // after xh --session=mysess GET http://localhost:8080/api/items
Defensive patterns
Strategy: validation
Validate before calling
if let Ok(u) = Url::parse(url) {
if u.host_str().is_none() || matches!(u.host_str(), Some(".") | Some("..")) {
eprintln!("URL must include a scheme and host for --session");
std::process::exit(2);
}
} Type guard
fn url_has_host(u: &Url) -> bool {
u.host_str().map(|h| h != "." && h != "..").unwrap_or(false)
} Try / catch
match result {
Err(e) if e.to_string().contains("extract host from url") => {
eprintln!("provide a full URL like https://host:port");
}
r => r?,
} Prevention
- Always pass absolute URLs (scheme + host) when using --session
- Never interpolate empty variables into the URL position
- Sanity-check URLs with a Url::parse + host check in scripts
When it happens
Trigger: Calling load_session/--session with a URL whose host cannot be parsed, e.g. a relative URL without scheme (`xh --session=name :8080/path` variants), an empty or malformed URL, or a URL whose host normalizes to '.' or '..'.
Common situations: Forgetting the scheme in the URL so it parses as a path; programmatic use building Url from user input; automated scripts substituting empty host variables.
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
- Inferred port number in --resolve from request URL.
- message-signature: RSA private keys require an explicit…
- Unsupported option
- Unknown option
- is not a valid value
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/c17969ab25643fc5.
Report an issue: GitHub.
Appendix: source
Thrown at src/session.rs:378
}
}
fn xh_version() -> String {
if test_mode() {
"0.0.0".into()
} else {
env!("CARGO_PKG_VERSION").into()
}
}
fn is_path(value: &OsString) -> bool {
value.to_string_lossy().contains(std::path::is_separator)
}
fn path_from_url(url: &Url) -> Result<String> {
match (url.host_str(), url.port()) {
(Some("."), _) | (Some(".."), _) | (None, _) => {
Err(anyhow!("couldn't extract host from url"))
}
(Some(host), Some(port)) => Ok(format!("{host}_{port}")),
(Some(host), None) => Ok(host.into()),
}
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
use reqwest::header::HeaderValue;
fn load_session_from_str(s: &str) -> Result<Session> {
Ok(Session {
url: Url::parse("http://example.net")?,
content: serde_json::from_str::<Content>(s)?.migrate(),
path: PathBuf::new(),View on GitHub (pinned to 2404aceecc)