browser-use/browser-use · error · ValueError

llm_screenshot_size must be a tuple of (width, height)

Error message

llm_screenshot_size must be a tuple of (width, height)

What it means

Agent.__init__ validation: llm_screenshot_size was provided but is not a 2-tuple. The parameter resizes screenshots sent to the LLM; the constructor requires exactly tuple(width, height) before it even looks at the LLM, failing fast on malformed config.

Source

Thrown at browser_use/agent/service.py:217

		include_recent_events: bool = False,
		sample_images: list[ContentPartTextParam | ContentPartImageParam] | None = None,
		final_response_after_failure: bool = True,
		enable_planning: bool = True,
		planning_replan_on_stall: int = 3,
		planning_exploration_limit: int = 5,
		loop_detection_window: int = 20,
		loop_detection_enabled: bool = True,
		llm_screenshot_size: tuple[int, int] | None = None,
		message_compaction: MessageCompactionSettings | bool | None = True,
		max_clickable_elements_length: int = 40000,
		_url_shortening_limit: int = 25,
		enable_signal_handler: bool = True,
		**kwargs,
	):
		# Validate llm_screenshot_size
		if llm_screenshot_size is not None:
			if not isinstance(llm_screenshot_size, tuple) or len(llm_screenshot_size) != 2:
				raise ValueError('llm_screenshot_size must be a tuple of (width, height)')
			width, height = llm_screenshot_size
			if not isinstance(width, int) or not isinstance(height, int):
				raise ValueError('llm_screenshot_size dimensions must be integers')
			if width < 100 or height < 100:
				raise ValueError('llm_screenshot_size dimensions must be at least 100 pixels')
			self.logger.info(f'🖼️  LLM screenshot resizing enabled: {width}x{height}')
		if llm is None:
			default_llm_name = CONFIG.DEFAULT_LLM
			if default_llm_name:
				from browser_use.llm.models import get_llm_by_name

				llm = get_llm_by_name(default_llm_name)
			else:
				# No default LLM specified, use the original default
				from browser_use import ChatBrowserUse

				llm = ChatBrowserUse()

View on GitHub (pinned to 6c73fced2f)

Solutions

  1. Convert to a tuple: llm_screenshot_size=(1280, 720)
  2. When loading from config: llm_screenshot_size=tuple(cfg['llm_screenshot_size'])
  3. Note the neighboring parameter (Browser window_size) accepts dicts — do not mix the two conventions

Example fix

# before
agent = Agent(task=..., llm=llm, llm_screenshot_size=[1024, 768])

# after
agent = Agent(task=..., llm=llm, llm_screenshot_size=(1024, 768))
Defensive patterns

Strategy: type-guard

Validate before calling

def normalize_screenshot_size(v):
    if v is None:
        return None
    v = tuple(v)
    assert len(v) == 2, 'llm_screenshot_size must have 2 items'
    return v

agent = Agent(task=..., llm=llm, llm_screenshot_size=normalize_screenshot_size(cfg_size))

Type guard

def is_valid_screenshot_size(v) -> bool:
    return v is None or (isinstance(v, tuple) and len(v) == 2)

Try / catch

null

Prevention

When it happens

Trigger: Passing a list [1280, 720] instead of a tuple; passing a single int; passing a 3-element tuple; passing None inside a config dict that gets unpacked with a wrong shape; passing a string '1280x720'.

Common situations: Loading Agent options from JSON/YAML where sequences arrive as lists; copy-pasting viewport-style dicts ({'width':..,'height':..}) which the Browser accepts but Agent does not for this param.

Related errors


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