ducaale/xh · error

The value passed to --proxy should be formatted as

Error message

The value passed to --proxy should be formatted as <PROTOCOL>:<PROXY_URL>

What it means

The --proxy argument requires the format <PROTOCOL>:<PROXY_URL>. The parser splits once on ':' and if it doesn't get exactly two parts (missing or too many separators), it returns this usage error without touching the URL.

Solutions

  1. Prefix the proxy URL with the protocol key: --proxy http:http://127.0.0.1:8080
  2. Ensure the entire PROTOCOL:URL string is quoted as one shell argument
  3. Use --proxy all:... if you want the proxy to apply to every scheme

Example fix

// before
xh --proxy 127.0.0.1:8080 GET https://example.com
// after
xh --proxy all:http://127.0.0.1:8080 GET https://example.com
Defensive patterns

Strategy: validation

Validate before calling

fn validate_proxy_format(arg: &str) -> Result<(), String> {
    if arg.is_empty() { return Err("empty --proxy value".into()); }
    let (proto, rest) = arg.split_once(':').ok_or("expected <PROTOCOL>:<PROXY_URL>")?;
    if proto.is_empty() || rest.is_empty() { return Err("empty protocol or URL".into()); }
    Ok(())
}

Try / catch

match ProxyArg::from_str(&arg) {
    Ok(p) => p,
    Err(e) if e.to_string().contains("should be formatted") =>
        eprintln!("Expected --proxy http:http://host:port"),
    Err(e) => eprintln!("--proxy rejected: {e}"),
}

Prevention

When it happens

Trigger: Passing --proxy http://127.0.0.1:8080 (no protocol prefix — splits into 'http' and '//127.0.0.1:8080' — wait, this actually parses; the real triggers are values with no colon at all, like --proxy 127.0.0.1:8080 if it had no colon, or empty value, or multiple colons leaving >2 parts in splitn(2) is impossible — so chiefly: a value with no ':' at all, e.g. --proxy localhost or --proxy "".

Common situations: Following curl-style --proxy URL syntax without the protocol key, empty proxy env in scripts, quoting stripped the argument so only the host remained.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13). Data as JSON: /api/errors/2aa8ec93d8a965c4. Report an issue: GitHub.

Appendix: source

Thrown at src/cli.rs:1246

        match split_arg[..] {
            [protocol, url] => {
                let url = reqwest::Url::try_from(url).map_err(|e| {
                    anyhow!(
                        "Invalid proxy URL '{}' for protocol '{}': {}",
                        url,
                        protocol,
                        e
                    )
                })?;

                match protocol.to_lowercase().as_str() {
                    "http" => Ok(Proxy::Http(url)),
                    "https" => Ok(Proxy::Https(url)),
                    "all" => Ok(Proxy::All(url)),
                    _ => Err(anyhow!("Unknown protocol to set a proxy for: {}", protocol)),
                }
            }
            _ => Err(anyhow!(
                "The value passed to --proxy should be formatted as <PROTOCOL>:<PROXY_URL>"
            )),
        }
    }
}

#[derive(Debug, Clone)]
pub struct Resolve {
    pub domain: String,
    pub addr: IpAddr,
}

impl FromStr for Resolve {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> anyhow::Result<Self> {
        if s.chars().filter(|&c| c == ':').count() == 2 {
            // More than two colons could mean an IPv6 address.

View on GitHub (pinned to 2404aceecc)