browser-use/browser-use · warning · ModelRateLimitError
str(e)
Error message
str(e)
What it means
In ChatCerebras.ainvoke's plain-text path (output_format is None), an openai.RateLimitError from client.chat.completions.create is re-raised as ModelRateLimitError with the SDK's message. Cerebras is accessed through the OpenAI-compatible SDK, so a 429 from Cerebras surfaces as RateLimitError and is normalized here so callers get one retryable error type.
Source
Thrown at browser_use/llm/cerebras/chat.py:129
common['top_p'] = self.top_p if self.seed is not None: common['seed'] = self.seed # ① Regular multi-turn conversation/text output if output_format is None: try: resp = await client.chat.completions.create( # type: ignore model=self.model, messages=cerebras_messages, # type: ignore **common, ) usage = self._get_usage(resp) return ChatInvokeCompletion( completion=resp.choices[0].message.content or '', usage=usage, ) except RateLimitError as e: raise ModelRateLimitError(str(e), model=self.name) from e except (APIError, APIConnectionError, APITimeoutError, APIStatusError) as e: raise ModelProviderError(str(e), model=self.name) from e except Exception as e: raise ModelProviderError(str(e), model=self.name) from e # ② JSON Output path (response_format) if output_format is not None and hasattr(output_format, 'model_json_schema'): try: # For Cerebras, we'll use a simpler approach without response_format # Instead, we'll ask the model to return JSON and parse it import json # Get the schema to guide the model schema = output_format.model_json_schema() schema_str = json.dumps(schema, indent=2) # Create a prompt that asks for the specific JSON structure json_prompt = f"""
View on GitHub (pinned to 6c73fced2f)
Solutions
- Retry with exponential backoff on ModelRateLimitError and cap concurrency (semaphore) across agents
- Check which limit was hit (RPM vs TPM) in the message text and pace requests accordingly — add small delays between agent steps if RPM-bound
- Cache or reuse extraction results to cut request volume; use page_extraction_llm on a separate provider
- Move to a paid Cerebras tier or higher limit if the workload is legitimate
Example fix
# before
resp = await llm.ainvoke(messages) # 429 -> ModelRateLimitError
# after
async def invoke_backoff(llm, messages, attempts=5):
for i in range(attempts):
try:
return await llm.ainvoke(messages)
except ModelRateLimitError:
if i == attempts - 1:
raise
await asyncio.sleep(2 ** i) Defensive patterns
Strategy: retry
Try / catch
from browser_use.exceptions import ModelRateLimitError
try:
out = await llm.ainvoke(messages)
except ModelRateLimitError:
await asyncio.sleep(30)
out = await llm.ainvoke(messages) # single bounded retry Prevention
- Track requests-per-minute against your Cerebras tier; pad delays between agent steps
- Separate keys or providers for main llm vs page_extraction_llm to split quotas
- Backoff on ModelRateLimitError uniformly across providers — the library normalizes the type for this purpose
When it happens
Trigger: Calling ainvoke without output_format while exceeding Cerebras free-tier rate limits (requests per minute/hour or tokens per minute); bursty agent steps issuing many completions in sequence; concurrent agents sharing one CEREBRAS_API_KEY.
Common situations: Cerebras free tier is generous in tokens but strict on requests-per-minute, so step-heavy browser agents trip it easily; CI parallelism; a retry loop amplifying request frequency after a slow response.
Related errors
- str(e)
- Rate limit exceeded. {error_detail}
- Failed to stop cloud browser: HTTP {response.status_code} -
- {error_message}
- {e.message}
AI-assisted analysis of browser-use/browser-use@6c73fced2f (2026-08-14).
Data as JSON: /api/errors/7329a860c8baa6ce.
Report an issue: GitHub.