SeleniumHQ/selenium · error · TypeError
Expected object of type ScrollOrigin, got: {type(scroll_orig
Error message
Expected object of type ScrollOrigin, got: {type(scroll_origin)} What it means
`ActionChains.scroll_from_origin` requires a `ScrollOrigin` object (built via `ScrollOrigin.from_element(...)` or `ScrollOrigin.from_viewport(...)`). Passing anything else (a WebElement, a string, a tuple) raises `TypeError`. ScrollOrigin bundles the origin plus x/y offsets and is the only acceptable argument shape.
Source
Thrown at py/selenium/webdriver/common/action_chains.py:362
def scroll_from_origin(self, scroll_origin: ScrollOrigin, delta_x: int, delta_y: int) -> ActionChains:
"""Scroll by a provided amount based on a scroll origin (element or viewport).
The scroll origin is either the center of an element or the upper left of the
viewport plus any offsets. If the origin is an element, and the element
is not in the viewport, the bottom of the element will first be
scrolled to the bottom of the viewport.
Args:
scroll_origin: Where scroll originates (viewport or element center) plus provided offsets.
delta_x: Distance along X axis to scroll using the wheel. A negative value scrolls left.
delta_y: Distance along Y axis to scroll using the wheel. A negative value scrolls up.
Raises:
MoveTargetOutOfBoundsException: If the origin with offset is outside the viewport.
"""
if not isinstance(scroll_origin, ScrollOrigin):
raise TypeError(f"Expected object of type ScrollOrigin, got: {type(scroll_origin)}")
self.w3c_actions.wheel_action.scroll(
origin=scroll_origin.origin,
x=scroll_origin.x_offset,
y=scroll_origin.y_offset,
delta_x=delta_x,
delta_y=delta_y,
)
return self
# Context manager so ActionChains can be used in a 'with .. as' statements.
def __enter__(self) -> ActionChains:
return self # Return created instance of self.
def __exit__(self, _type, _value, _traceback) -> None:
pass # Do nothing, does not require additional cleanup.
View on GitHub (pinned to aa36b38e69)
Solutions
- Wrap an element origin: `from selenium.webdriver.common.actions.wheel_input import ScrollOrigin; ActionChains(driver).scroll_from_origin(ScrollOrigin.from_element(el, 0, 0), 0, 100).perform()`.
- Wrap a viewport origin: `ScrollOrigin.from_viewport(x_offset, y_offset)`.
- If you just want to scroll to an element, use `scroll_to_element(element)` instead.
- If you want pure delta scroll, use `scroll_by_amount(delta_x, delta_y)`.
Example fix
// before ActionChains(driver).scroll_from_origin(element, 0, 100).perform() # TypeError // after from selenium.webdriver.common.actions.wheel_input import ScrollOrigin ActionChains(driver).scroll_from_origin(ScrollOrigin.from_element(element), 0, 100).perform()
Defensive patterns
Strategy: type-guard
Validate before calling
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin origin = ScrollOrigin.from_element(element, 0, 0) assert isinstance(origin, ScrollOrigin), "scroll_from_origin needs a ScrollOrigin" ActionChains(driver).scroll_from_origin(origin, 0, 100).perform()
Type guard
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin
def is_scroll_origin(value) -> bool:
return isinstance(value, ScrollOrigin) Try / catch
try:
ActionChains(driver).scroll_from_origin(origin, dx, dy).perform()
except TypeError:
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin
if hasattr(origin, "id"):
origin = ScrollOrigin.from_element(origin)
else:
origin = ScrollOrigin.from_viewport()
ActionChains(driver).scroll_from_origin(origin, dx, dy).perform() Prevention
- Always wrap origins with ScrollOrigin.from_element / from_viewport.
- Use scroll_to_element or scroll_by_amount for simpler cases.
- Type-hint the parameter as ScrollOrigin to catch mistakes statically.
When it happens
Trigger: `ActionChains(driver).scroll_from_origin(element, 0, 100)` (passing a WebElement directly), `scroll_from_origin("viewport", 0, 100)` (a string), or `scroll_from_origin((0,0), 0, 100)` (a tuple). The developer forgot to wrap the origin in a ScrollOrigin.
Common situations: Mixing up `scroll_from_origin` with `scroll_to_element`/`scroll_by_amount`. Porting code from another library. Reading an outdated tutorial that passed a bare element.
Related errors
- ClipRectangle must be an instance of ClipRectangle. Received
- Value must be an instance of BytesValue. Received: '${value}
- CookieHeader must be an instance of Header. Received:'${head
- Header value must be an instance of Header. Received:'${head
- CookieHeader must be an instance of Header. Received:'${head
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/5096aa518c05a462.
Report an issue: GitHub.