zeroclaw-labs/zeroclaw · error · anyhow::Error
URL cannot contain whitespace
Error message
URL cannot contain whitespace
What it means
Thrown by HttpRequestTool::validate_url_policy (crates/zeroclaw-tools/src/http_request.rs:127) when the URL, after leading/trailing trimming, still contains any whitespace character (space, tab, newline) anywhere in it. The http_request tool rejects such URLs before scheme or allowlist checks because unencoded whitespace is invalid in an HTTP request target and can be used to smuggle or corrupt headers. It is a fail-closed input-validation error, not a network error.
Source
Thrown at crates/zeroclaw-tools/src/http_request.rs:127
config_path: Some(config_path),
secrets_encrypt,
})
}
#[cfg(test)]
fn validate_url(&self, raw_url: &str) -> anyhow::Result<String> {
Ok(self.validate_url_policy(raw_url)?.url)
}
fn validate_url_policy(&self, raw_url: &str) -> anyhow::Result<HttpRequestUrlPolicy> {
let url = raw_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");
}
if self.allowed_domains.is_empty() {
anyhow::bail!(
"HTTP request tool is enabled but no allowed_domains are configured. Add [http_request].allowed_domains in config.toml"
);
}
let host = extract_host(url)?;
if let Ok(ip) = host.parse::<IpAddr>() {
if domain_guard::is_known_cloud_metadata_endpoint(ip) {
anyhow::bail!("Blocked cloud metadata host: {host}");
}
if domain_guard::is_cloud_metadata_ip(ip) {View on GitHub (pinned to 88bb9c8533)
Solutions
- Percent-encode every space and control character in the path/query before calling the tool (space -> %20, tab -> %09, newline -> %0A).
- Trim the URL and assert it has no interior whitespace before invoking http_request.
- Build URLs with a URL encoder (e.g. url::Url with query_pairs_mut, or urlencoding::encode) instead of raw string concatenation.
Example fix
// before
let args = json!({"url": "https://example.com/hello world"});
tool.execute(args).await?; // -> URL cannot contain whitespace
// after
let args = json!({"url": "https://example.com/hello%20world"});
tool.execute(args).await?; Defensive patterns
Strategy: validation
Validate before calling
fn url_is_clean(url: &str) -> bool {
let t = url.trim();
!t.is_empty() && !t.chars().any(char::is_whitespace)
} Type guard
fn has_interior_whitespace(url: &str) -> bool {
url.trim().chars().any(char::is_whitespace)
} Try / catch
let result = tool.execute(args).await?;
if let Some(err) = &result.error {
if err.contains("URL cannot contain whitespace") {
// percent-encode the URL and retry once with sanitized input
}
} Prevention
- Always build URLs with a URL encoder; never interpolate raw strings into the path or query.
- Trim and whitespace-check URLs at the boundary where user/model input enters your system.
- Reject or encode tabs/newlines early; they are almost always injection artifacts.
When it happens
Trigger: Calling tool.execute with args.url = "https://example.com/hello world" (unencoded space in the path); a URL pasted from a terminal that contains a tab or a line-wrap newline; building the URL by string concatenation where one variable carries interior whitespace. Leading/trailing whitespace alone does NOT trigger it because the URL is trimmed first; only interior whitespace does.
Common situations: LLM/agent-generated URLs containing natural-language fragments; URLs copied from documentation that wrapped across lines; query strings assembled with raw spaces instead of percent-encoding; templating code that interpolates unvalidated user input into the path or query.
Related errors
- Only http:// and https:// URLs are allowed
- URL host has unmatched IPv6 brackets
- providers.models.{profile_name}.uri must use http/https
- URL cannot contain whitespace
- URL cannot be empty
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/760a41b45bbacce4.
Report an issue: GitHub.