stablyai/orca · warning · RuntimeError
window_not_focused: keyboard input requires the target windo
Error message
window_not_focused: keyboard input requires the target window to be focused; retry with --restore-window
What it means
Raised by require_keyboard_focus (runtime.py:192) when the target window is not ACTIVE and the caller did NOT set operation.get('restoreWindow'). This is the 'hint to retry correctly' variant: the bridge detected keyboard input would go to the wrong window and tells the caller exactly how to fix the next attempt — pass restoreWindow so the bridge attempts to activate the window first (the path in error 493). Contrast with 493 which fires when restoreWindow WAS set but failed.
Source
Thrown at native/computer-use-linux/runtime.py:192
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
def require_keyboard_focus(window, operation):
if has_state(window, Atspi.StateType.ACTIVE):
return
if operation.get("restoreWindow"):
deadline = time.monotonic() + 0.5
while time.monotonic() < deadline:
if has_state(window, Atspi.StateType.ACTIVE):
return
time.sleep(0.05)
if has_state(window, Atspi.StateType.ACTIVE):
return
raise RuntimeError("window_not_focused: keyboard input requires the target window to be focused; restoreWindow was requested but the target window is still not focused; bring it forward manually or check desktop permissions")
raise RuntimeError("window_not_focused: keyboard input requires the target window to be focused; retry with --restore-window")
def app_matches(app, query):
needle = str(query or "").strip().lower()
if not needle:
return False
if needle.startswith("pid:"):
requested_pid = parse_positive_pid(needle[4:])
return requested_pid is not None and pid_of(app) == requested_pid
if needle.isdigit() and int(needle) > 0 and pid_of(app) == int(needle):
return True
haystacks = [name_of(app).lower()] + [name_of(window).lower() for _, window in windows_for(app)]
return any(value == needle or needle in value for value in haystacks)
def parse_positive_pid(value):
return int(value) if value.isdigit() and int(value) > 0 else None
View on GitHub (pinned to 1136503c6a)
Solutions
- Retry the same operation with restoreWindow:true — the bridge will attempt grab_focus/xdotool before requiring focus.
- Always pair keyboard operations with restoreWindow unless you've just verified focus via get-app-state's focusedSummary.
- After a click on app A, optionally verify with a fresh snapshot that A holds ACTIVE before typing.
- If restoreWindow still fails (error 493), restore focus manually.
Example fix
// before — keyboard op without restore
{ "app": "Firefox", "tool": "type_text", "text": "hi" }
// after — let the bridge activate the window first
{ "app": "Firefox", "tool": "type_text", "text": "hi", "restoreWindow": true } Defensive patterns
Strategy: retry
Validate before calling
# If window lacks focus, set restoreWindow before dispatch
if not window_has_focus(window):
operation = {**operation, 'restoreWindow': True} Type guard
def needs_restore_window(window, operation) -> bool:
return not has_state(window, Atspi.StateType.ACTIVE) and not operation.get('restoreWindow') Try / catch
try:
run_operation(operation)
except RuntimeError as exc:
if 'retry with --restore-window' in str(exc):
operation = {**operation, 'restoreWindow': True}
run_operation(operation)
else:
raise Prevention
- Always pair keyboard operations (type_text, press_key, hotkey, paste_text) with restoreWindow:true.
- After clicks that don't change focus (accessibility-path clicks), verify focus via get-app-state before typing.
- Wrap keyboard ops in a retry that adds restoreWindow on this specific message.
When it happens
Trigger: type_text/press_key/hotkey/paste_text operation dispatched while another window has focus, and the operation JSON omitted 'restoreWindow' (or set it false). The AT-SPI ACTIVE state belongs to a different window, so synthetic keys (Atspi.generate_keyboard_event) would land in the wrong app.
Common situations: Agent performed a click in app A (which may or may not have activated it depending on the click path), then immediately called type_text without restoreWindow, and the previously-focused app B still holds ACTIVE. Common after accessibility-path clicks that don't change focus.
Related errors
- window_not_focused: keyboard input requires the target windo
- No top-level AT-SPI window is available for {app}
- windowId is not supported by the Linux AT-SPI provider; use
- windowNotFound("{window_index}")
- Linux computer use requires an active desktop session; missi
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/cc970a2b26fa38ad.
Report an issue: GitHub.