{"record":{"id":"49c6fcbb67fe49f5","repo":"stablyai/orca","slug":"unsupported-scroll-direction-direction","errorCode":null,"errorMessage":"unsupported scroll direction: {direction}","messagePattern":"unsupported scroll direction: (.+?)","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"native/computer-use-linux/runtime.py","lineNumber":893,"sourceCode":"        subprocess.run(\n            [xdotool, *[item for modifier in reversed(modifier_keys) for item in (\"keyup\", modifier)]],\n            check=False,\n            timeout=2,\n        )\n\n\ndef scroll_at(x, y, direction, pages):\n    if direction is None or str(direction).strip() == \"\":\n        raise RuntimeError(\"direction is required\")\n    direction = str(direction).lower()\n    wheel_events = {\n        \"up\": (\"b4p\", \"b4r\"),\n        \"down\": (\"b5p\", \"b5r\"),\n        \"left\": (\"b6p\", \"b6r\"),\n        \"right\": (\"b7p\", \"b7r\"),\n    }\n    if direction not in wheel_events:\n        raise RuntimeError(f\"unsupported scroll direction: {direction}\")\n    down, up = wheel_events[direction]\n    page_count = max(1, math.ceil(require_positive_number(1 if pages is None else pages, \"pages\")))\n    for _ in range(page_count):\n        Atspi.generate_mouse_event(round(x), round(y), \"abs\")\n        Atspi.generate_mouse_event(round(x), round(y), down)\n        time.sleep(0.03)\n        Atspi.generate_mouse_event(round(x), round(y), up)\n\n\ndef drag_between(start, end):\n    Atspi.generate_mouse_event(round(start[0]), round(start[1]), \"abs\")\n    Atspi.generate_mouse_event(round(start[0]), round(start[1]), \"b1p\")\n    for step in range(1, 13):\n        x = start[0] + (end[0] - start[0]) * step / 12\n        y = start[1] + (end[1] - start[1]) * step / 12\n        Atspi.generate_mouse_event(round(x), round(y), \"abs\")\n        time.sleep(0.02)\n    Atspi.generate_mouse_event(round(end[0]), round(end[1]), \"b1r\")","sourceCodeStart":875,"sourceCodeEnd":911,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/native/computer-use-linux/runtime.py#L875-L911","documentation":"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.","triggerScenarios":"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).","commonSituations":"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'.","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."],"exampleFix":"// before\n{\"tool\":\"scroll\",\"direction\":\"towards-bottom\"}\n// after\n{\"tool\":\"scroll\",\"direction\":\"down\"}","handlingStrategy":"type-guard","validationCode":"DIRECTIONS = {\"up\", \"down\", \"left\", \"right\"}\ndirection = str(raw_direction).strip().lower()\nif direction not in DIRECTIONS:\n    raise ValueError(f\"direction must be one of {sorted(DIRECTIONS)}\")\nop = {\"tool\": \"scroll\", \"direction\": direction}","typeGuard":"def is_scroll_direction(value) -> bool:\n    return str(value).strip().lower() in {\"up\", \"down\", \"left\", \"right\"}","tryCatchPattern":"try:\n    run_operation(op)\nexcept RuntimeError as e:\n    if \"unsupported scroll direction\" in str(e):\n        op[\"direction\"] = \"down\"\n    else:\n        raise","preventionTips":["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."],"tags":["validation","input-validation","computer-use","scroll","python"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}