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

Unsupported text browser '{browser}'. Supported: {}

Error message

Unsupported text browser '{browser}'. Supported: {}

What it means

resolve_browser validates a caller-requested browser name against SUPPORTED_BROWSERS, the fixed list ["lynx","links","w3m"], after trimming and lowercasing it. A name outside that list — even a real browser like elinks, browsh, or firefox — bails with the supported set printed in the message.

Source

Thrown at crates/zeroclaw-tools/src/text_browser.rs:146

            if let Ok(output) = tokio::process::Command::new("which")
                .arg(browser)
                .output()
                .await
                && output.status.success()
            {
                return Some((*browser).to_string());
            }
        }
        None
    }

    /// Resolve which browser to use: prefer configured, then auto-detect.
    async fn resolve_browser(&self, requested: Option<&str>) -> anyhow::Result<String> {
        // If the caller explicitly requested a browser via the tool parameter, use it.
        if let Some(browser) = requested {
            let browser = browser.trim().to_lowercase();
            if !SUPPORTED_BROWSERS.contains(&browser.as_str()) {
                anyhow::bail!(
                    "Unsupported text browser '{browser}'. Supported: {}",
                    SUPPORTED_BROWSERS.join(", ")
                );
            }
            // Verify it's installed
            let installed = tokio::process::Command::new("which")
                .arg(&browser)
                .output()
                .await
                .map(|o| o.status.success())
                .unwrap_or(false);
            if !installed {
                anyhow::bail!("Requested text browser '{browser}' is not installed");
            }
            return Ok(browser);
        }

        // If a preferred browser is set in config, try it first.

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Use lynx, links, or w3m exactly (case-insensitive)
  2. Omit the browser parameter entirely to let the tool auto-detect an installed one from the supported set
  3. Install one of the three if none is present (see the 'not installed' error)

Example fix

// before
{"url":"https://example.com","browser":"elinks"}
// after
{"url":"https://example.com","browser":"lynx"}
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED: &[&str] = &["lynx","links","w3m"];
let b = requested.trim().to_lowercase();
if !SUPPORTED.contains(&b.as_str()) { /* omit browser and let auto-detect run */ }

Type guard

fn is_supported_browser(b: &str) -> bool {
    ["lynx","links","w3m"].contains(&b.trim().to_lowercase().as_str())
}

Try / catch

Err(e) if e.to_string().starts_with("Unsupported text browser") => {
    // retry once with browser omitted so resolve_browser auto-detects
}

Prevention

When it happens

Trigger: Tool parameter browser set to "elinks", "browsh", "firefox", "chromium", or any name not in the list; correct names still work in any case ("Lynx" passes after normalization).

Common situations: Users assuming any terminal or GUI browser works; elinks is the most common surprise since it is a popular lynx fork but absent from the list; configs copied from other tools that accept broader browser names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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