{ "version": "1.0", "ok": false, "command": "click", "error": { "code": "STALE_REF", "message": "@e7 not found in current RefMap", "suggestion": "Run 'snapshot' to refresh, then retry with updated ref" }}
Source:crates/core/src/output.rs:34
Errors are returned as JSON on stdout with exit code 1. Parse the JSON to get structured error details.
UI changed after snapshot (window opened, dialog appeared, element moved)
Snapshot executed for different app
Multiple agents sharing same refmap file
Recovery pattern:
# Attempt actionagent-desktop click @e5# → STALE_REF# Re-snapshot to get fresh refsagent-desktop snapshot --app Safari -i# Extract new ref ID for the target element# (Agent logic: parse JSON, find element by role/name, get new ref_id)# Retry with new refagent-desktop click @e3 # Note: ID may have changed# → Success
Prevention:
Always snapshot immediately before action sequences
Re-snapshot after any UI state change (alerts, menus, modals)
Cause: Specified window ID doesn’t exist or was closed.
{ "code": "WINDOW_NOT_FOUND", "message": "Window w-4521 not found", "suggestion": "Use 'list-windows' to see available windows"}
Recovery:
# List all windowsagent-desktop list-windows# List windows for specific appagent-desktop list-windows --app Finder# Use current window IDagent-desktop snapshot --window-id w-9876 -i
Cause: OS rejected the action or accessibility API call failed.
{ "code": "ACTION_FAILED", "message": "Click action failed on @e5", "suggestion": "Element may not support this action. Try 'get @e5 actions' to see available actions", "platform_detail": "AXError -25204: Action not supported"}
Common triggers:
Element doesn’t support the action (e.g., clicking a label)
Element disabled or not interactive
Application busy or unresponsive
Permission issue for specific action
Recovery:
# Check available actionsagent-desktop get @e5 actions# Verify element is enabledagent-desktop get @e5 enabled# → {"value": "true"}# Try alternative actionagent-desktop focus @e5 # Instead of click
Cause: Action type not supported by the element or platform.
{ "code": "ACTION_NOT_SUPPORTED", "message": "Toggle action not supported by statictext elements", "suggestion": "This element does not support the requested action"}
Example:
# Invalid: Can't toggle a labelagent-desktop toggle @e7# → ACTION_NOT_SUPPORTED (if @e7 is statictext)# Valid: Toggle checkboxagent-desktop toggle @e9# → Success (if @e9 is checkbox)
def perform_action_with_retry(action_cmd, snapshot_cmd): """Retry action once if ref is stale.""" result = subprocess.run(action_cmd, capture_output=True, text=True) if result.returncode == 0: return json.loads(result.stdout) error = json.loads(result.stdout).get("error", {}) if error.get("code") == "STALE_REF": # Re-snapshot to get fresh refs subprocess.run(snapshot_cmd, check=True) # Agent must re-parse tree and extract new ref ID here # Then retry action with new ref raise Exception("Re-snapshot required - update ref ID and retry") raise Exception(f"{error.get('code')}: {error.get('message')}")
def safe_click(ref_id): """Verify element exists and is enabled before clicking.""" # Check if element exists result = subprocess.run( ["agent-desktop", "get", ref_id, "enabled"], capture_output=True, text=True ) if result.returncode != 0: error = json.loads(result.stdout)["error"] if error["code"] in ["STALE_REF", "ELEMENT_NOT_FOUND"]: raise Exception("Element no longer exists - re-snapshot required") data = json.loads(result.stdout)["data"] if data.get("value") == "false": raise Exception(f"Element {ref_id} is disabled") # Perform click result = subprocess.run( ["agent-desktop", "click", ref_id], capture_output=True, text=True ) return json.loads(result.stdout)