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

  1. Retry with exponential backoff on ModelRateLimitError and cap concurrency (semaphore) across agents
  2. 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
  3. Cache or reuse extraction results to cut request volume; use page_extraction_llm on a separate provider
  4. 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

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


AI-assisted analysis of browser-use/browser-use@6c73fced2f (2026-08-14). Data as JSON: /api/errors/7329a860c8baa6ce. Report an issue: GitHub.