browser-use/browser-use · error · RuntimeError

Target element is not visible

Error message

Target element is not visible

What it means

A registered action declares `available_file_paths` (the allow-list of file paths the agent may touch) with no default, and the injected value was None. The wrapper fails fast because file-access actions must be constrained to a known path list; None would mean unrestricted or broken file access.

Source

Thrown at browser_use/actor/element.py:614

		if source_position:
			source_x = source_position['x']
			source_y = source_position['y']
		else:
			source_box = await self.get_bounding_box()
			if not source_box:
				raise RuntimeError('Source element is not visible')
			source_x = source_box['x'] + source_box['width'] / 2
			source_y = source_box['y'] + source_box['height'] / 2

		# Get target coordinates
		if isinstance(target, dict) and 'x' in target and 'y' in target:
			target_x = target['x']
			target_y = target['y']
		else:
			if target_position:
				target_box = await target.get_bounding_box()
				if not target_box:
					raise RuntimeError('Target element is not visible')
				target_x = target_box['x'] + target_position['x']
				target_y = target_box['y'] + target_position['y']
			else:
				target_box = await target.get_bounding_box()
				if not target_box:
					raise RuntimeError('Target element is not visible')
				target_x = target_box['x'] + target_box['width'] / 2
				target_y = target_box['y'] + target_box['height'] / 2

		# Perform drag operation
		await self._client.send.Input.dispatchMouseEvent(
			{'type': 'mousePressed', 'x': source_x, 'y': source_y, 'button': 'left'},
			session_id=self._session_id,
		)

		await self._client.send.Input.dispatchMouseEvent(
			{'type': 'mouseMoved', 'x': target_x, 'y': target_y},
			session_id=self._session_id,

View on GitHub (pinned to 6c73fced2f)

Solutions

  1. Pass the allow-list explicitly: await my_action(available_file_paths=['/data/out.csv'], file_system=FileSystem()).
  2. Set Agent(available_file_paths=[...]) so the built-in injection has a value.
  3. If the list is genuinely dynamic, make the parameter optional (default None) and resolve paths inside the action with your own checks.

Example fix

# before
result = await save_file(path='out.csv', content='x')  # available_file_paths missing

# after
agent = Agent(task=..., llm=llm, available_file_paths=['/workspace/out.csv'])
# or directly:
result = await save_file(path='out.csv', content='x', available_file_paths=['/workspace/out.csv'])
Defensive patterns

Strategy: validation

Validate before calling

from inspect import signature, Parameter

def file_paths_wired(func, provided: dict) -> bool:
    p = signature(func).parameters.get('available_file_paths')
    if p is None or p.default is not Parameter.empty:
        return True
    return bool(provided.get('available_file_paths'))

Type guard

def requires_available_file_paths(func) -> bool:
    p = inspect.signature(func).parameters.get('available_file_paths')
    return p is not None and p.default is inspect.Parameter.empty

Try / catch

try:
    await action(**kwargs)
except ValueError as e:
    if 'requires available_file_paths' in str(e):
        await action(**kwargs, available_file_paths=ALLOWED_PATHS)

Prevention

When it happens

Trigger: Invoking a file action with available_file_paths=None, or from an Agent/tools context where available_file_paths was not configured (Agent parameter of the same name left unset while a custom action requires it).

Common situations: Custom file actions that mirrored the built-in write_file/read_file signature; using Tools standalone without the agent-level available_file_paths wiring; forgetting to set Agent(available_file_paths=[...]) when running actions manually.

Related errors


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