sgl-project/sglang · error · ValueError

Unknown browser action

Error message

Unknown browser action: {recipient}

What it means

SGLang's browser tool dispatcher received a recipient starting with 'browser.' that is not one of the supported actions (browser.search, browser.open, browser.find). This indicates an unrecognized or misspelled browser action name.

Solutions

  1. Check the exact recipient string against the supported set: browser.search/browser.open/browser.find
  2. Upgrade SGLang if a newer browser action is required and supported in a later release
  3. Re-prompt the model to use one of the supported actions

Example fix

# before
recipient = "browser.navigate"
# after
recipient = "browser.open"  # with {"url": "..."}
Defensive patterns

Strategy: fallback

Validate before calling

SUPPORTED = {"browser.search", "browser.open", "browser.find"}
recipient = last_msg.recipient
assert recipient in SUPPORTED, f"unsupported browser action: {recipient}"

Type guard

def is_supported_browser_action(recipient: str) -> bool:
    return recipient in {"browser.search", "browser.open", "browser.find"}

Try / catch

try:
    out = await tool._dispatch_browser_call(context, recipient, args)
except ValueError as e:
    if str(e).startswith("Unknown browser action"):
        out = await tool._dispatch_browser_call(context, "browser.search", {"query": str(args)})

Prevention

When it happens

Trigger: Dispatching e.g. 'browser.navigate', 'browser.click', or 'browser.Search' (wrong case) through get_result or run_tool_flow.

Common situations: Model hallucinating an unlisted browser action, a typo in a manually crafted tool call, or newer model tool schemas advertising actions this SGLang version does not implement (version mismatch after upgrade).

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/92a240b48c8bfa96. Report an issue: GitHub.

Appendix: source

Thrown at python/sglang/srt/entrypoints/tool.py:87

        if recipient == "browser.search":
            query = args.get("query")
            if not query:
                raise ValueError("browser.search requires a query")
            data = await self.exa_client.search(query)
            return self._format_search_results(context, query, data)

        if recipient == "browser.open":
            url = self._resolve_url(context, args)
            data = await self.exa_client.contents([url])
            return self._format_page_contents(context, url, data)

        if recipient == "browser.find":
            pattern = args.get("pattern")
            if not pattern:
                raise ValueError("browser.find requires a pattern")
            return await self._find_pattern(context, args, pattern)

        raise ValueError(f"Unknown browser action: {recipient}")

    def _browser_state(self, context: "ConversationContext") -> dict[str, Any]:
        state = getattr(context, "_sglang_exa_browser_state", None)
        if state is None:
            state = {"pages": {}, "page_text": {}}
            setattr(context, "_sglang_exa_browser_state", state)
        return state

    def _format_search_results(
        self, context: "ConversationContext", query: str, data: dict[str, Any]
    ) -> str:
        state = self._browser_state(context)
        state["pages"] = {}
        state["page_text"] = {}

        results = data.get("results") or []
        request_id = data.get("requestId")
        if request_id:

View on GitHub (pinned to 0132848349)