{"record":{"id":"40a5ede9e0ab3263","repo":"zeroclaw-labs/zeroclaw","slug":"browser-tool-is-enabled-but-no-allowed-domains-are","errorCode":null,"errorMessage":"Browser tool is enabled but no allowed_domains are configured. Add [browser].allowed_domains in config.toml","messagePattern":"Browser tool is enabled but no allowed_domains are configured\\. Add \\[browser\\]\\.allowed_domains in config\\.toml","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/browser_open.rs","lineNumber":59,"sourceCode":"    }\n\n    fn validate_url(&self, raw_url: &str) -> anyhow::Result<String> {\n        let url = raw_url.trim();\n\n        if url.is_empty() {\n            anyhow::bail!(\"URL cannot be empty\");\n        }\n\n        if url.chars().any(char::is_whitespace) {\n            anyhow::bail!(\"URL cannot contain whitespace\");\n        }\n\n        if !(url.starts_with(\"https://\") || url.starts_with(\"http://\")) {\n            anyhow::bail!(\"Only http:// or https:// URLs are allowed\");\n        }\n\n        if self.allowed_domains.is_empty() && self.allowed_private_hosts.is_empty() {\n            anyhow::bail!(\n                \"Browser tool is enabled but no allowed_domains are configured. Add [browser].allowed_domains in config.toml\"\n            );\n        }\n\n        let host = extract_host(url)?;\n        let private_host = domain_guard::is_private_or_local_host(&host);\n        let private_host_allowed = private_host\n            && domain_guard::host_matches_allowlist(&host, &self.allowed_private_hosts);\n\n        if private_host && !private_host_allowed {\n            anyhow::bail!(\"Blocked local/private host: {host}\");\n        }\n\n        if private_host_allowed {\n            return Ok(url.to_string());\n        }\n\n        if !domain_guard::host_matches_allowlist(&host, &self.allowed_domains) {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/browser_open.rs#L41-L77","documentation":"browser_open is fail-closed: if both allowed_domains and allowed_private_hosts are empty, every URL is rejected with this configuration error, because an allowlist-less browser tool would open anything. The message points at the fix — [browser].allowed_domains in config.toml.","triggerScenarios":"Enabling the browser_open tool without configuring [browser].allowed_domains (and not configuring allowed_private_hosts either), then invoking it with any URL.","commonSituations":"Fresh installs where the tool ships disabled and gets enabled without its config section; TOML typos such as [browser_allowed] so the section is never read; teams removing a broad wildcard entry for security and forgetting the tool now refuses everything.","solutions":["Add [browser] allowed_domains = [\"example.com\", ...] to config.toml and restart","For local development targets, use [browser].allowed_private_hosts instead","Verify the TOML section and key names match the schema exactly so the lists actually load"],"exampleFix":"# config.toml — before\n# (no [browser] section)\n\n# after\n[browser]\nallowed_domains = [\"example.com\", \"docs.example.com\"]","handlingStrategy":"validation","validationCode":"// startup check before wiring the tool\nif allowed_domains.is_empty() && allowed_private_hosts.is_empty() {\n    return Err(\"browser_open enabled without [browser].allowed_domains — refusing to start fail-open\".into());\n}","typeGuard":null,"tryCatchPattern":"match open_tool.execute(args).await {\n    Ok(res) if res.success => { /* ... */ }\n    Ok(res) => {\n        if res.error.as_deref().unwrap_or_default().contains(\"no allowed_domains are configured\") {\n            // configuration error: fix config.toml and restart, not retryable\n        }\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Validate the [browser] config section at startup, not at first tool call","Use a config linter or schema check for config.toml keys","After intentionally clearing an allowlist, disable the browser tool too"],"tags":["browser-open","configuration","allowlist","fail-closed","setup"],"backgroundTag":"missing-allowlist-config","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}