{"record":{"id":"254e11aab3568561","repo":"stablyai/orca","slug":"windowid-is-not-supported-by-the-linux-at-spi-prov","errorCode":null,"errorMessage":"windowId is not supported by the Linux AT-SPI provider; use windowIndex","messagePattern":"windowId is not supported by the Linux AT-SPI provider; use windowIndex","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"native/computer-use-linux/runtime.py","lineNumber":149,"sourceCode":"            yield app\n\n\ndef windows_for(app):\n    result = []\n    for index, child in children(app):\n        role = role_of(child).lower()\n        rect = screen_rect(child)\n        if rect is not None or role in {\"frame\", \"window\", \"dialog\", \"alert\"}:\n            result.append((index, child))\n    return result\n\n\ndef choose_window(app, window_id=None, window_index=None):\n    windows = windows_for(app)\n    if not windows:\n        raise RuntimeError(\"No top-level AT-SPI window is available for \" + name_of(app))\n    if window_id is not None:\n        raise RuntimeError(\"windowId is not supported by the Linux AT-SPI provider; use windowIndex\")\n    if window_index is not None:\n        for item in windows:\n            if item[0] == int(window_index):\n                return item\n        raise RuntimeError(f'windowNotFound(\"{window_index}\")')\n    for item in windows:\n        if has_state(item[1], Atspi.StateType.ACTIVE):\n            return item\n    for item in windows:\n        if has_state(item[1], Atspi.StateType.SHOWING):\n            return item\n    return windows[0]\n\n\ndef restore_window(app, window=None):\n    target = window if window is not None else app\n    component = attempt(target.get_component_iface)\n    if component is not None and attempt(lambda: Atspi.Component.grab_focus(component), False):","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/native/computer-use-linux/runtime.py#L131-L167","documentation":"Raised by choose_window (runtime.py:148-149) when window_id is not None — i.e., the operation JSON included a 'windowId' field. The Linux AT-SPI provider does not support stable window ids (AT-SPI windows have no durable identifier, only positional indices), so any non-null windowId is rejected unconditionally with a message redirecting to windowIndex. This is a hard API contract: windowId is the macOS concept; windowIndex is the Linux equivalent.","triggerScenarios":"run_operation received an operation dict where operation.get('windowId') returned a non-null value. Caused by a cross-platform caller that always populates windowId, or by an agent that read a snapshot's 'windowId' field (always null on Linux, see line 670) and echoed it back as a target.","commonSituations":"An agent or orchestrator built against the macOS computer-use API invoking the Linux bridge unchanged; a snapshot consumer that didn't notice windowId is null on Linux and tried to target a window by id.","solutions":["Replace 'windowId' with 'windowIndex' in the operation JSON for Linux targets — use the index returned in make_snapshot's windowIndex field.","On the caller side, branch by platform: send windowId on macOS, windowIndex on Linux.","Strip windowId before dispatching to the Linux runtime so choose_window never sees it.","If you need stable targeting across window reorders, target by element index within a fresh get-app-state snapshot instead."],"exampleFix":"// before — cross-platform op uses windowId\n{ \"app\": \"Firefox\", \"windowId\": \"main\", \"tool\": \"click\", \"x\": 10, \"y\": 10 }\n\n// after — Linux uses windowIndex\n{ \"app\": \"Firefox\", \"windowIndex\": 0, \"tool\": \"click\", \"x\": 10, \"y\": 10 }","handlingStrategy":"validation","validationCode":"# Strip windowId for Linux before dispatch\nop = dict(operation)\nif op.get('windowId') is not None:\n    op.pop('windowId')\n    # or translate to windowIndex if you have one\n    if 'windowIndex' not in op:\n        op['windowIndex'] = 0  # let choose_window pick active/showing/first","typeGuard":"def is_linux_window_id_unsupported(operation: dict) -> bool:\n    return operation.get('windowId') is not None","tryCatchPattern":"try:\n    run_operation(operation)\nexcept RuntimeError as exc:\n    if 'windowId is not supported' in str(exc):\n        operation = {k: v for k, v in operation.items() if k != 'windowId'}\n        operation['windowIndex'] = 0\n        run_operation(operation)\n    else:\n        raise","preventionTips":["Branch operation JSON by platform: windowId on macOS, windowIndex on Linux.","Always strip windowId before dispatching to the Linux runtime.","Use windowIndex from a fresh get-app-state response, not a cached windowId."],"tags":["linux","at-spi","window","api-contract","cross-platform"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}