stablyai/orca · error · RuntimeError
direction is required
Error message
direction is required
What it means
Raised by scroll_at (runtime.py:884) when direction is None or strips to an empty string. Direction is a required field for the scroll tool because the wheel-event mapping (up/down/left/right) depends on it. This fires before the direction is lowercased and looked up.
Source
Thrown at native/computer-use-linux/runtime.py:884
command = [xdotool, "mousemove", "--sync", str(round(x)), str(round(y))]
for modifier in modifier_keys:
command.extend(["keydown", modifier])
command.extend(["click", "--repeat", str(count), "--delay", "35", button_number])
for modifier in reversed(modifier_keys):
command.extend(["keyup", modifier])
try:
subprocess.run(command, check=True, timeout=5)
finally:
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)
View on GitHub (pinned to 1136503c6a)
Solutions
- Always set 'direction' to one of 'up', 'down', 'left', 'right' for scroll operations.
- If your controller has a default scroll direction, populate the field explicitly before dispatch.
- Reject empty direction in your own input layer rather than relying on the runtime.
Example fix
// before
{"tool":"scroll","pages":2}
// after
{"tool":"scroll","direction":"down","pages":2} Defensive patterns
Strategy: validation
Validate before calling
DIRECTIONS = {"up", "down", "left", "right"}
direction = (raw_direction or "").strip().lower()
if direction not in DIRECTIONS:
direction = "down" # sane default
op = {"tool": "scroll", "direction": direction} Type guard
def is_scroll_direction(value) -> bool:
return (value or "").strip().lower() in {"up", "down", "left", "right"} Try / catch
try:
run_operation(op)
except RuntimeError as e:
if "direction is required" in str(e):
op["direction"] = "down"
else:
raise Prevention
- Always set 'direction' explicitly for scroll operations.
- Default to a direction in your controller rather than sending empty.
- Validate direction before dispatch.
When it happens
Trigger: Calling the 'scroll' tool with operation['direction'] missing, null, or whitespace-only (' '). An empty string after .strip() is treated as absent.
Common situations: An agent omits direction assuming a default; a caller forwards a templated field that resolved to empty; whitespace from a malformed JSON value.
Related errors
- unsupported scroll direction: {direction}
- {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/1d08485adb82338c.
Report an issue: GitHub.