{"record":{"id":"90ba418adf1129c5","repo":"zeroclaw-labs/zeroclaw","slug":"blocked-local-private-host-host-to-allow-this","errorCode":null,"errorMessage":"Blocked local/private host: {host}. To allow this host, add it (or \"*\") to {tool_name}.allowed_private_hosts in config.toml","messagePattern":"Blocked local/private host: (.+?)\\. To allow this host, add it \\(or \"\\*\"\\) to (.+?)\\.allowed_private_hosts in config\\.toml","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/web_fetch.rs","lineNumber":742,"sourceCode":"    let host = extract_host(url)?;\n\n    // blocked_domains always takes precedence\n    if domain_guard::host_matches_allowlist(&host, blocked_domains) {\n        anyhow::bail!(\"Host '{host}' is in {tool_name}.blocked_domains\");\n    }\n\n    let host_is_private_or_local = domain_guard::is_private_or_local_host(&host);\n    let private_match = private_allowlist_match(&host, allowed_private_hosts);\n    // An explicit entry (a specific host/IP or suffix) is a deliberate per-host\n    // carve-out; the \"*\" wildcard blanket-tolerates a private/internal\n    // resolution for any host. The distinction only affects the WARN below.\n    let private_explicit = matches!(private_match, PrivateAllow::Explicit);\n    // Either an explicit entry or \"*\" tolerates a private/internal host: it lifts\n    // the literal private-host block and skips the resolved-IP public check.\n    let private_tolerated = !matches!(private_match, PrivateAllow::None);\n\n    if host_is_private_or_local && !private_tolerated {\n        anyhow::bail!(\n            \"Blocked local/private host: {host}. \\\n             To allow this host, add it (or \\\"*\\\") to \\\n             {tool_name}.allowed_private_hosts in config.toml\"\n        );\n    }\n\n    if private_explicit || (private_tolerated && host_is_private_or_local) {\n        ::zeroclaw_log::record!(\n            WARN,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                .with_outcome(::zeroclaw_log::EventOutcome::Unknown)\n                .with_attrs(::serde_json::json!({\"tool_name\": tool_name, \"host\": host})),\n            \"web_fetch: allowing host via allowed_private_hosts\"\n        );\n    }\n\n    let skip_allowed_domains = host_is_private_or_local && private_tolerated;\n","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/web_fetch.rs#L724-L760","documentation":"Error \"Blocked local/private host: {host}. To allow this host, add it (or \"*\") to {tool_name}.allowed_private_hosts in config.toml\" thrown in zeroclaw-labs/zeroclaw.","triggerScenarios":"Thrown at crates/zeroclaw-tools/src/web_fetch.rs:742 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Add the host (or \"*\") to <tool_name>.allowed_private_hosts in config.toml if this is intended."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}