{"record":{"id":"667439662361f867","repo":"sgl-project/sglang","slug":"browser-search-requires-a-query","errorCode":null,"errorMessage":"browser.search requires a query","messagePattern":"browser\\.search requires a query","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/entrypoints/tool.py","lineNumber":72,"sourceCode":"\n        try:\n            args = orjson.loads(last_msg.content[0].text)\n            result_text = await self._dispatch_browser_call(context, recipient, args)\n        except Exception as exc:\n            logger.exception(\"Browser tool call failed\")\n            result_text = f\"Browser tool call failed: {exc}\"\n\n        content = TextContent(text=result_text)\n        author = Author(role=Role.TOOL, name=recipient)\n        return [Message(author=author, content=[content], recipient=Role.ASSISTANT)]\n\n    async def _dispatch_browser_call(\n        self, context: \"ConversationContext\", recipient: str, args: dict[str, Any]\n    ) -> str:\n        if recipient == \"browser.search\":\n            query = args.get(\"query\")\n            if not query:\n                raise ValueError(\"browser.search requires a query\")\n            data = await self.exa_client.search(query)\n            return self._format_search_results(context, query, data)\n\n        if recipient == \"browser.open\":\n            url = self._resolve_url(context, args)\n            data = await self.exa_client.contents([url])\n            return self._format_page_contents(context, url, data)\n\n        if recipient == \"browser.find\":\n            pattern = args.get(\"pattern\")\n            if not pattern:\n                raise ValueError(\"browser.find requires a pattern\")\n            return await self._find_pattern(context, args, pattern)\n\n        raise ValueError(f\"Unknown browser action: {recipient}\")\n\n    def _browser_state(self, context: \"ConversationContext\") -> dict[str, Any]:\n        state = getattr(context, \"_sglang_exa_browser_state\", None)","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/tool.py#L54-L90","documentation":"SGLang's browser tool dispatch rejects a browser.search action whose parsed JSON arguments contain no truthy 'query' field. The search path requires at least a query string before it can call the underlying Exa search client.","triggerScenarios":"Dispatching recipient 'browser.search' with args like {}, {\"query\": \"\"}, or {\"query\": null} after orjson parsing of the message content.","commonSituations":"A model emitting malformed/empty tool arguments (hallucinated schema), a client constructing browser.search calls manually without a query, or JSON schema drift where the field was renamed (e.g. q instead of query).","solutions":["Ensure the tool-call JSON includes a non-empty \"query\" string","Validate args before dispatch and re-prompt the model to correct empty arguments","Align the tool schema advertised to the model with {\"query\": string, required}"],"exampleFix":"# before\nargs = {\"q\": \"sglang\"}\n# after\nargs = {\"query\": \"sglang\"}","handlingStrategy":"validation","validationCode":"args = orjson.loads(last_msg.content[0].text)\nif not args.get(\"query\"):\n    raise ValueError(\"browser.search requires a query\")  # fail fast client-side","typeGuard":"def valid_search_args(args: dict) -> bool:\n    return isinstance(args.get(\"query\"), str) and bool(args[\"query\"].strip())","tryCatchPattern":"try:\n    out = await tool._dispatch_browser_call(context, \"browser.search\", args)\nexcept ValueError as e:\n    if \"requires a query\" in str(e):\n        args[\"query\"] = fallback_query  # or re-prompt the model\n        out = await tool._dispatch_browser_call(context, \"browser.search\", args)","preventionTips":["Validate parsed tool JSON against the tool schema before dispatch","Advertise required parameters clearly in the tool prompt/schema"],"tags":["browser","search","argument-validation","tool-calling"],"backgroundTag":"missing-required-tool-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}