{"record":{"id":"f609efb6ee0bbbf7","repo":"zeroclaw-labs/zeroclaw","slug":"browser-open-is-not-supported-on-this-os","errorCode":null,"errorMessage":"browser_open is not supported on this OS","messagePattern":"browser_open is not supported on this OS","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/browser_open.rs","lineNumber":270,"sourceCode":"        let mut brave_error = String::new();\n        for cmd in [\"brave\", \"brave.exe\"] {\n            let mut command = tokio::process::Command::new(cmd);\n            command.arg(url);\n            match run_browser_launcher(command, cmd).await {\n                Ok(()) => return Ok(()),\n                Err(error) => brave_error = error,\n            }\n        }\n\n        anyhow::bail!(\n            \"Failed to open URL with default browser launcher: {primary_error}. Brave compatibility fallback also failed: {brave_error}\"\n        );\n    }\n\n    #[cfg(not(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\")))]\n    {\n        let _ = url;\n        anyhow::bail!(\"browser_open is not supported on this OS\");\n    }\n}\n\nfn extract_host(url: &str) -> anyhow::Result<String> {\n    let rest = url\n        .strip_prefix(\"https://\")\n        .or_else(|| url.strip_prefix(\"http://\"))\n        .ok_or_else(|| {\n            ::zeroclaw_log::record!(\n                WARN,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                    .with_attrs(::serde_json::json!({\"url\": url})),\n                \"browser_open: unsupported URL scheme rejected\"\n            );\n            anyhow::Error::msg(\"Only http:// or https:// URLs are allowed\")\n        })?;\n","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/browser_open.rs#L252-L288","documentation":"open_in_system_browser has cfg branches for macOS, Linux, and Windows only; on any other target OS the final #[cfg(not(any(...)))] branch discards the URL and bails with this message (browser_open.rs:267-271). The tool compiles anywhere, but execution is a hard refusal on unsupported platforms. There is no fallback path at all on such targets.","triggerScenarios":"Running the zeroclaw runtime with BrowserOpenTool registered on FreeBSD, OpenBSD, Solaris/illumos, or a non-desktop target like android/ios that is not macos/linux/windows at compile time.","commonSituations":"Cross-compiling or deploying the agent to BSD-based servers or niche Unix flavors where the tool registry was copied over wholesale without platform gating.","solutions":["Do not register BrowserOpenTool on that platform; gate its construction/registration with #[cfg(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\"))].","If the platform has a working opener (e.g. 'open' on FreeBSD when the xdg-open port is installed), treat it as Linux-like and add a cfg branch upstream.","Route URL-opening through a channel message instead of the local browser on unsupported OSes."],"exampleFix":"// before: tool registered unconditionally\ntools.push(BrowserOpenTool::new(security, domains)?.into());\n\n// after: only on supported desktop platforms\n#[cfg(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\"))]\ntools.push(BrowserOpenTool::new(security, domains)?.into());","handlingStrategy":"validation","validationCode":"// Compile-time gate: never construct the tool on unsupported platforms.\n#[cfg(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\"))]\nfn register_browser_tool(tools: &mut Vec<Box<dyn Tool>>, security: Arc<SecurityPolicy>, domains: Vec<String>) -> anyhow::Result<()> {\n    tools.push(BrowserOpenTool::new(security, domains)?.into());\n    Ok(())\n}\n\n#[cfg(not(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\")))]\nfn register_browser_tool(_tools: &mut Vec<Box<dyn Tool>>, _security: Arc<SecurityPolicy>, _domains: Vec<String>) -> anyhow::Result<()> {\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate BrowserOpenTool registration behind #[cfg(any(macos, linux, windows))].","On BSD/niche Unix, route links through a channel message instead of the local browser.","Smoke-test tool registries on every target platform in CI to catch cfg gaps."],"tags":["platform-support","cfg","rust","browser","zeroclaw"],"backgroundTag":"unsupported-platform","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}