stablyai/orca · error · RuntimeError
unsupported scroll direction: {direction}
Error message
unsupported scroll direction: {direction} What it means
Raised by scroll_at (runtime.py:893) when the lowercased direction is not a key in wheel_events — i.e. not one of 'up', 'down', 'left', 'right'. These map to AT-SPI mouse button codes b4/b5/b6/b7 (the four wheel axes). It fires only for non-empty, unrecognized directions; empty ones are caught earlier by error 507.
Source
Thrown at native/computer-use-linux/runtime.py:893
subprocess.run(
[xdotool, *[item for modifier in reversed(modifier_keys) for item in ("keyup", modifier)]],
check=False,
timeout=2,
)
def scroll_at(x, y, direction, pages):
if direction is None or str(direction).strip() == "":
raise RuntimeError("direction is required")
direction = str(direction).lower()
wheel_events = {
"up": ("b4p", "b4r"),
"down": ("b5p", "b5r"),
"left": ("b6p", "b6r"),
"right": ("b7p", "b7r"),
}
if direction not in wheel_events:
raise RuntimeError(f"unsupported scroll direction: {direction}")
down, up = wheel_events[direction]
page_count = max(1, math.ceil(require_positive_number(1 if pages is None else pages, "pages")))
for _ in range(page_count):
Atspi.generate_mouse_event(round(x), round(y), "abs")
Atspi.generate_mouse_event(round(x), round(y), down)
time.sleep(0.03)
Atspi.generate_mouse_event(round(x), round(y), up)
def drag_between(start, end):
Atspi.generate_mouse_event(round(start[0]), round(start[1]), "abs")
Atspi.generate_mouse_event(round(start[0]), round(start[1]), "b1p")
for step in range(1, 13):
x = start[0] + (end[0] - start[0]) * step / 12
y = start[1] + (end[1] - start[1]) * step / 12
Atspi.generate_mouse_event(round(x), round(y), "abs")
time.sleep(0.02)
Atspi.generate_mouse_event(round(end[0]), round(end[1]), "b1r")View on GitHub (pinned to 1136503c6a)
Solutions
- Map your direction vocabulary to 'up'/'down'/'left'/'right' before sending the operation.
- Validate direction against an allowlist in your controller.
- Treat diagonal/other directions as two separate scroll calls on different axes.
Example fix
// before
{"tool":"scroll","direction":"towards-bottom"}
// after
{"tool":"scroll","direction":"down"} Defensive patterns
Strategy: type-guard
Validate before calling
DIRECTIONS = {"up", "down", "left", "right"}
direction = str(raw_direction).strip().lower()
if direction not in DIRECTIONS:
raise ValueError(f"direction must be one of {sorted(DIRECTIONS)}")
op = {"tool": "scroll", "direction": direction} Type guard
def is_scroll_direction(value) -> bool:
return str(value).strip().lower() in {"up", "down", "left", "right"} Try / catch
try:
run_operation(op)
except RuntimeError as e:
if "unsupported scroll direction" in str(e):
op["direction"] = "down"
else:
raise Prevention
- Map any custom direction vocabulary to up/down/left/right before sending.
- Maintain an allowlist and validate against it in your controller.
- Normalize case and whitespace before validation.
When it happens
Trigger: operation['direction'] for the scroll tool is a value like 'north', 'top', 'vertical', 'scroll-down', or 'UP' (case-insensitive match is handled, so case is not the issue).
Common situations: An agent uses a natural-language direction that isn't normalized; a caller exposes a different vocabulary ('north'/'south') and forgets to map it; a typo like 'dwon'.
Related errors
- direction is required
- {name} must be a positive number
- {name} is required
- unsupported mouse button: {button}
- click modifiers require modifier keys only
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/49c6fcbb67fe49f5.
Report an issue: GitHub.