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

HTTP request tool is enabled but no allowed_domains are conf

Error message

HTTP request tool is enabled but no allowed_domains are configured. Add [http_request].allowed_domains in config.toml

What it means

Thrown by HttpRequestTool::validate_url_policy (crates/zeroclaw-tools/src/http_request.rs:135) when the tool is enabled but its allowed_domains list is empty. The http_request tool is allowlist-only by design (fail closed): with no allowlist configured it cannot decide what is permitted, so every request is rejected before any DNS or network work. The message tells you the exact config.toml key to add.

Source

Thrown at crates/zeroclaw-tools/src/http_request.rs:135

    }

    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) {
                anyhow::bail!(
                    "Blocked link-local host: {host}; 169.254.0.0/16 is blocked unconditionally \
                     because cloud metadata services are hosted in that range"
                );
            }
        }
        let port = extract_port(url)?;

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add the allowlist to config.toml, e.g. [http_request] with allowed_domains = ["example.com", "api.github.com"], then restart.
  2. Use allowed_domains = ["*"] if you truly want all public hosts (private/metadata hosts stay blocked regardless).
  3. If constructing the tool programmatically, pass a non-empty Vec<String> of domains to HttpRequestTool::new/new_with_config.

Example fix

# before
# config.toml has no [http_request] section -> every request fails

# after
[http_request]
allowed_domains = ["example.com", "api.github.com"]
Defensive patterns

Strategy: validation

Validate before calling

if allowed_domains.is_empty() {
    anyhow::bail!("refusing to enable http_request: set [http_request].allowed_domains in config.toml");
}
let tool = HttpRequestTool::new_with_config(security, allowed_domains, /* ... */)?;

Try / catch

let result = tool.execute(args).await?;
if let Some(err) = &result.error {
    if err.contains("no allowed_domains are configured") {
        // surface a setup error to the operator; do not retry
    }
}

Prevention

When it happens

Trigger: Constructing HttpRequestTool::new(...) with an empty allowed_domains Vec; enabling the http_request tool in config.toml without an [http_request] section; a config.toml where the [http_request] table exists but allowed_domains is missing, commented out, or set to an empty array; CI using a minimal config that omitted the section.

Common situations: Fresh installs or docker images shipped without the [http_request] block; config refactors that renamed or dropped the key; test harnesses reusing a trimmed-down config; deployments that assumed the tool works allow-all by default.

Related errors


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