zeroclaw-labs/zeroclaw · warning · anyhow::Error

URL cannot contain whitespace

Error message

URL cannot contain whitespace

What it means

validate_text_browser_url rejects any URL containing whitespace characters after trimming (spaces, tabs, newlines anywhere inside the string). This catches malformed URLs that would otherwise be split, misparsed, or smuggled past later host checks.

Source

Thrown at crates/zeroclaw-tools/src/text_browser.rs:222

    fn build_dump_args(_browser: &str, url: &str) -> Vec<String> {
        // All supported browsers (lynx, links, w3m) use the same `-dump` flag
        vec!["-dump".to_string(), url.to_string()]
    }
}

fn validate_text_browser_url(
    url: &str,
    allowed_private_hosts: &[String],
    validate_dns: impl FnOnce(&str, bool) -> anyhow::Result<()>,
) -> anyhow::Result<String> {
    let url = url.trim();

    if url.is_empty() {
        anyhow::bail!("URL cannot be empty");
    }

    if url.chars().any(char::is_whitespace) {
        anyhow::bail!("URL cannot contain whitespace");
    }

    if !url.starts_with("http://") && !url.starts_with("https://") {
        anyhow::bail!("Only http:// and https:// URLs are allowed");
    }

    let parsed = reqwest::Url::parse(url)
        .map_err(|e| anyhow::Error::msg(format!("Invalid URL format: {e}")))?;

    if !parsed.username().is_empty() || parsed.password().is_some() {
        anyhow::bail!("URL userinfo is not allowed");
    }

    let host_str = parsed
        .host_str()
        .ok_or_else(|| anyhow::Error::msg("URL must include a host"))?;

    let bare_host = host_str.trim_start_matches('[').trim_end_matches(']');

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Percent-encode spaces and other unsafe characters (%20) before submitting
  2. Strip stray newlines/tabs from pasted input (the tool only trims ends, not inner whitespace)
  3. Build URLs with a proper encoder (e.g. urlencoding::encode for query values) instead of string concatenation

Example fix

// before
let url = format!("https://example.com/search?q={query}"); // q="rust web"
// after
let url = format!("https://example.com/search?q={}", urlencoding::encode(&query));
Defensive patterns

Strategy: validation

Validate before calling

if url.chars().any(char::is_whitespace) {
    let cleaned: String = url.split_whitespace().collect(); // or percent-encode properly
}

Type guard

fn url_has_no_inner_whitespace(u: &str) -> bool { !u.trim().chars().any(char::is_whitespace) }

Try / catch

Err(e) if e.to_string() == "URL cannot contain whitespace" => {
    // percent-encode the offending segments and retry once
}

Prevention

When it happens

Trigger: URLs like "https://example.com/a b", copy-pasted URLs containing a newline or tab, or a space before the fragment/query; also unescaped spaces in query parameters built via string concatenation.

Common situations: Pasting URLs from PDFs or chat messages that carry soft line breaks; building URLs with format! and forgetting percent-encoding for values that contain spaces.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/fd65a5970837eec6. Report an issue: GitHub.