browser-use/browser-use · error · ModelProviderError

No response from model

Error message

No response from model

What it means

Raised in ChatGoogle's fallback path when response.text is empty ('No response text in fallback mode'): the model supports neither parsed output nor any usable text. ModelProviderError with status 500. Unlike [247] this branch is inside the generic retry loop, so the configured retry policy (max_retries with exponential backoff) may retry it before it propagates.

Source

Thrown at browser_use/llm/google/chat.py:512

								# Parse and validate
								parsed_data = json.loads(text)
								return ChatInvokeCompletion(
									completion=output_format.model_validate(parsed_data),
									usage=usage,
									stop_reason=self._get_stop_reason(response),
								)
							except (json.JSONDecodeError, ValueError) as e:
								self.logger.error(f'❌ Failed to parse fallback JSON: {str(e)}')
								self.logger.debug(f'Raw response text: {response.text[:200]}...')
								raise ModelProviderError(
									message=f'Model does not support JSON mode and failed to parse JSON from text response: {str(e)}',
									status_code=500,
									model=self.model,
								) from e
						else:
							self.logger.error('❌ No response text in fallback mode')
							raise ModelProviderError(
								message='No response from model',
								status_code=500,
								model=self.model,
							)
			except Exception as e:
				elapsed = time.time() - start_time
				self.logger.error(f'💥 API call failed after {elapsed:.2f}s: {type(e).__name__}: {e}')
				# Re-raise the exception
				raise

		# Retry logic for certain errors with exponential backoff
		assert self.max_retries >= 1, 'max_retries must be at least 1'

		for attempt in range(self.max_retries):
			try:
				return await _make_api_call()
			except ModelProviderError as e:
				# Retry if status code is in retryable list and we have attempts left

View on GitHub (pinned to 6c73fced2f)

Solutions

  1. Check candidates[0].finish_reason and safety ratings in the response to identify the empty-text cause
  2. If thinking/reasoning consumed the budget, raise max_output_tokens or disable thinking config
  3. Retry transient empties: the call sits inside the retry loop, so verify max_retries > 1
  4. Switch models to one with JSON-mode support so response.parsed is populated
Defensive patterns

Strategy: retry

Type guard

def is_empty_fallback_response(err: ModelProviderError) -> bool:
    return err.message == 'No response from model'

Try / catch

except ModelProviderError as e:
    if err.message == 'No response from model' and attempt < max_retries - 1:
        await asyncio.sleep(2 ** attempt)
        continue
    raise

Prevention

When it happens

Trigger: Gemini returns an empty candidate (safety block, RECITATION finish, zero-token MAX_TOKENS finish, or API hiccup) while output_format is set and JSON mode is unavailable for the chosen model.

Common situations: Safety filters on scraping-heavy agent tasks; preview model outages; thinking budget consuming the entire token allowance leaving no visible text.

Related errors


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