sgl-project/sglang · error · ValueError
Unknown browser action: {recipient}
Error message
Unknown browser action: {recipient} What it means
The recipient string starts with 'browser.' but is not one of the recognized browser actions (browser.search, browser.find/open as handled above), so parse_output_message cannot map it to an ActionSearch/ActionFind and rejects it.
Source
Thrown at python/sglang/srt/entrypoints/harmony_utils.py:277
content = message.content[0]
browser_call = orjson.loads(content.text)
# TODO: translate to url properly!
if recipient == "browser.search":
action = ActionSearch(
query=f"cursor:{browser_call.get('query', '')}", type="search"
)
elif recipient == "browser.open":
action = ActionOpenPage(
url=f"cursor:{browser_call.get('url', '')}", type="open_page"
)
elif recipient == "browser.find":
action = ActionFind(
pattern=browser_call["pattern"],
url=f"cursor:{browser_call.get('url', '')}",
type="find",
)
else:
raise ValueError(f"Unknown browser action: {recipient}")
web_search_item = ResponseFunctionWebSearch(
id=f"ws_{random_uuid()}",
action=action,
status="completed",
type="web_search_call",
)
output_items.append(web_search_item)
elif message.channel == "analysis":
for content in message.content:
reasoning_item = ResponseReasoningItem(
id=f"rs_{random_uuid()}",
type="reasoning",
summary=[],
content=[
ResponseReasoningTextContent(
text=content.text, type="reasoning_text"
)
],View on GitHub (pinned to 0132848349)
Solutions
- Restrict the advertised browser tools to browser.search/browser.find so the model only emits supported recipients
- Add a parser branch in harmony_utils.py for the new browser action if you genuinely need it
- Sanitize/normalize unknown browser.* recipients to a supported action or drop the message before parsing
Example fix
# before
msg.with_recipient("browser.click")
# after
msg.with_recipient("browser.search") # only supported browser actions Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_BROWSER_ACTIONS = {"browser.search", "browser.find", "browser.open"}
if message.recipient in {None} | SUPPORTED_BROWSER_ACTIONS or not message.recipient.startswith("browser."):
... # proceed Type guard
def is_supported_browser_action(recipient: str) -> bool:
return not recipient.startswith("browser.") or recipient in {"browser.search", "browser.find", "browser.open"} Try / catch
try:
items = parse_output_message(message)
except ValueError as e:
if "Unknown browser action" in str(e):
return [] # ignore unsupported action
raise Prevention
- Only advertise browser.search/browser.find in tool definitions
- Keep tool schema and parser branches in sync when adding browser actions
When it happens
Trigger: A message with recipient 'browser.click', 'browser.navigate', or any 'browser.<anything>' outside the supported action set reaching the parsing stage.
Common situations: Prompting the model to use browser tools the runtime doesn't implement; a new browser action added to the tool schema without a corresponding parser branch; model hallucinating tool names.
Related errors
- Invalid number of contents in browser message
- No call message found for {call_id}
- Unknown input type: {response_msg['type']}
- Unknown output type: {type(output)}
- Unknown recipient: {message.recipient}
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/30e721a0cc4fe7c1.
Report an issue: GitHub.