{"record":{"id":"9c80da982297303d","repo":"browser-use/browser-use","slug":"str-e-9c80da","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"exception","errorClass":"ModelRateLimitError","httpStatus":null,"severity":"warning","filePath":"browser_use/llm/deepseek/chat.py","lineNumber":131,"sourceCode":"\t\t\tif ds_messages and isinstance(ds_messages[-1], dict) and ds_messages[-1].get('role') == 'assistant':\n\t\t\t\tds_messages[-1]['prefix'] = True\n\t\t\tif stop:\n\t\t\t\tcommon['stop'] = stop\n\n\t\t# ① Regular multi-turn conversation/text output\n\t\tif output_format is None and not tools:\n\t\t\ttry:\n\t\t\t\tresp = await client.chat.completions.create(  # type: ignore\n\t\t\t\t\tmodel=self.model,\n\t\t\t\t\tmessages=ds_messages,  # type: ignore\n\t\t\t\t\t**common,\n\t\t\t\t)\n\t\t\t\treturn ChatInvokeCompletion(\n\t\t\t\t\tcompletion=resp.choices[0].message.content or '',\n\t\t\t\t\tusage=None,\n\t\t\t\t)\n\t\t\texcept RateLimitError as e:\n\t\t\t\traise ModelRateLimitError(str(e), model=self.name) from e\n\t\t\texcept (APIError, APIConnectionError, APITimeoutError, APIStatusError) as e:\n\t\t\t\traise ModelProviderError(str(e), model=self.name) from e\n\t\t\texcept Exception as e:\n\t\t\t\traise ModelProviderError(str(e), model=self.name) from e\n\n\t\t# ② Function Calling path (with tools or output_format)\n\t\tif tools or (output_format is not None and hasattr(output_format, 'model_json_schema')):\n\t\t\ttry:\n\t\t\t\tcall_tools = tools\n\t\t\t\ttool_choice = None\n\t\t\t\tif output_format is not None and hasattr(output_format, 'model_json_schema'):\n\t\t\t\t\ttool_name = output_format.__name__\n\t\t\t\t\tschema = SchemaOptimizer.create_optimized_json_schema(output_format)\n\t\t\t\t\tschema.pop('title', None)\n\t\t\t\t\tcall_tools = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'type': 'function',\n\t\t\t\t\t\t\t'function': {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/browser-use/browser-use/blob/6c73fced2f6d45a11d88622fe56365a5fe18f28b/browser_use/llm/deepseek/chat.py#L113-L149","documentation":"In ChatDeepSeek.ainvoke's plain-text path (no output_format and no tools), an openai.RateLimitError from client.chat.completions.create is re-raised as ModelRateLimitError with the SDK message. DeepSeek is called via the OpenAI-compatible SDK, so a 429 from api.deepseek.com is normalized into the library's retryable error type.","triggerScenarios":"Calling ainvoke with neither tools nor output_format while exceeding DeepSeek's per-key rate limits; concurrent agents sharing one DEEPSEEK_API_KEY; rapid step loops in browser automation; demand spikes on DeepSeek's service (their 429s also occur during regional congestion).","commonSituations":"DeepSeek free/discount时段 congestion (off-peak throttling is common and announced); parallel CI agents; aggressive retry loops without backoff amplifying request rate.","solutions":["Retry with exponential backoff on ModelRateLimitError; DeepSeek 429s are frequently transient congestion","Serialize or limit concurrent agents per key","Shift heavy runs out of peak congestion windows when DeepSeek announces throttling","Check balance/limits on the DeepSeek platform dashboard — sustained 429 can indicate a top-up or tier issue"],"exampleFix":"# before\nhistory = await agent.run()  # DEEPSEEK 429 mid-run\n\n# after\nasync def run_retry(agent, n=5):\n    for i in range(n):\n        try:\n            return await agent.run()\n        except ModelRateLimitError:\n            if i == n - 1: raise\n            await asyncio.sleep(2 ** i)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from browser_use.exceptions import ModelRateLimitError\n\nasync def deepseek_run(agent, attempts=5):\n    for i in range(attempts):\n        try:\n            return await agent.run()\n        except ModelRateLimitError:\n            if i == attempts - 1:\n                raise\n            await asyncio.sleep(min(120, 2 ** i))  # deepseek 429s can need longer windows","preventionTips":["Use longer backoff ceilings for DeepSeek — congestion-driven 429s resolve over minutes, not seconds","Schedule heavy runs outside DeepSeek's announced throttling windows","Keep per-key concurrency low; share load across keys only within ToS"],"tags":["rate-limit","deepseek","retry","http-429","openai-sdk"],"backgroundTag":null,"analyzedSha":"6c73fced2f6d45a11d88622fe56365a5fe18f28b","analyzedAt":"2026-08-14T19:42:40.557Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}