stablyai/orca · warning · RuntimeError
stale element frame; run get-app-state again and use a fresh
Error message
stale element frame; run get-app-state again and use a fresh element index
What it means
Raised by screen_point (runtime.py:791-796) when saved_element is not None (the caller passed an element index from a prior snapshot) but the live AT-SPI node's screen_rect returned None — meaning the element no longer has a visible extent (was scrolled off-screen, removed, hidden, or its window closed). Because the caller provided an element reference rather than explicit x/y, there is no coordinate fallback, so the bridge tells the caller the cached element is stale and to refresh.
Source
Thrown at native/computer-use-linux/runtime.py:796
for index in range(int(attempt(node.get_n_actions, 0) or 0)):
label = str(attempt(lambda i=index: node.get_action_name(i), "") or "").lower()
if label in priority:
return index
if fallback is None and any(term in label for term in ("click", "press", "activate")):
fallback = index
return fallback
def perform_action(node, index):
return bool(index is not None and attempt(lambda: node.do_action(int(index)), False))
def screen_point(window_rect, saved_element=None, x=None, y=None, node=None):
rect = screen_rect(node) if node is not None else None
if rect is not None:
return rect.x + rect.width / 2, rect.y + rect.height / 2
if saved_element is not None:
raise RuntimeError("stale element frame; run get-app-state again and use a fresh element index")
if window_rect is None or x is None or y is None:
raise RuntimeError("coordinate action requires a visible window and coordinates")
return window_rect.x + float(x), window_rect.y + float(y)
def require_positive_integer(value, name):
try:
parsed = int(value)
except (TypeError, ValueError):
raise RuntimeError(f"{name} must be a positive integer")
if parsed <= 0:
raise RuntimeError(f"{name} must be a positive integer")
return parsed
def require_positive_number(value, name):
try:
parsed = float(value)View on GitHub (pinned to 1136503c6a)
Solutions
- Call get-app-state again to obtain a fresh snapshot and use a new element index.
- Target by explicit x/y coordinates (operation.x/y) instead of an element handle when the UI is volatile.
- After UI-changing actions (clicks that navigate, scrolls), refresh the snapshot before referencing element indices.
- Reduce the time between snapshot and action to minimize reflow windows.
Example fix
// before — reusing a stale element index after UI changed
{ "app": "Browser", "element": 42, "tool": "click" } // element 42 no longer has a rect
// after — refresh snapshot, then target fresh index or coordinates
// 1. call get-app-state
// 2. find the element's new index (or its current x/y)
{ "app": "Browser", "x": 320, "y": 480, "tool": "click" } Defensive patterns
Strategy: retry
Validate before calling
# Before acting on an element, verify it still has a rect
node = find_element(app, saved_element)
if node is not None and screen_rect(node) is None:
# element is stale — refresh snapshot before action
snapshot = make_snapshot(query, include_screenshot=False)
# re-resolve the element index from the fresh snapshot Type guard
def element_has_live_rect(app, saved_element) -> bool:
node = find_element(app, saved_element)
return node is not None and screen_rect(node) is not None Try / catch
try:
point = screen_point(bounds, saved_element, x, y, node)
except RuntimeError as exc:
if 'stale element frame' in str(exc):
snapshot = make_snapshot(query, include_screenshot=False)
# re-acquire element index or fall back to explicit x/y from the fresh snapshot
point = screen_point(bounds, None, fresh_x, fresh_y, None)
else:
raise Prevention
- Call get-app-state before referencing element indices after any UI-changing action.
- Prefer explicit x/y coordinates when the UI is volatile.
- Minimize the interval between snapshot and action to reduce reflow windows.
When it happens
Trigger: click/scroll/drag operation referenced operation.get('element') (a saved element handle) whose underlying AT-SPI node now returns no extent: UI reflowed (list scrolled, dialog dismissed, view switched), element recycled/removed, or window resized so the element is off-screen. screen_rect returns None when get_component_iface is null or width/height ≤ 0.
Common situations: Agent cached an element index from a get-app-state snapshot, performed intermediate actions that reflowed the UI, then tried to act on the stale element. Web apps with dynamic lists, virtualized scrollers, and route changes are common culprits; native apps with collapsing sidebars/animations also trigger it.
Related errors
- windowNotFound("{window_index}")
- coordinate action requires a visible window and coordinates
- Linux computer use requires an active desktop session; missi
- No top-level AT-SPI window is available for {app}
- windowId is not supported by the Linux AT-SPI provider; use
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/2618b46ac7e6a8ce.
Report an issue: GitHub.