Skip to content

fix: split Desktop Agent OS errors into recoverable vs unfixable - #307

Merged
philipph-askui merged 1 commit into
mainfrom
fix/desktop-agent-os-recoverable-exception
Aug 13, 2026
Merged

fix: split Desktop Agent OS errors into recoverable vs unfixable#307
philipph-askui merged 1 commit into
mainfrom
fix/desktop-agent-os-recoverable-exception

Conversation

@philipph-askui

Copy link
Copy Markdown
Contributor

Problem

When a tool that talks to the Desktop Agent OS fails — for example, reading a remote file or listing a directory that does not exist — the whole agent run crashed with an unhandled error, instead of the failure being reported back to the agent as a tool error (the way other tool failures are handled).

The reason: the Desktop Agent OS error type inherited from BaseException. The tool-calling loop catches tool failures with except Exception and converts them into an error result the agent can react to, but except Exception does not catch BaseException subclasses, so the error slipped past and propagated all the way up.

Approach

Rather than simply reparenting the single error type (see the discussion on the previous attempt), this splits Desktop Agent OS errors into two types, matching how the codebase already distinguishes fatal from recoverable errors in the tool-calling loop:

  • DesktopAgentOsException (recoverable) — a plain Exception for failures the agent can react to and work around (e.g. a path that does not exist, or file contents that cannot be decoded). The loop's generic except Exception catches it and surfaces it to the agent as a tool error result, so the run continues.
  • DesktopAgentOsError (unfixable) — now inherits from AutomationError, for protocol violations (unexpected response type, a response missing both an error and a payload). The loop's existing except (AgentError, AutomationError): raise re-raises it, terminating the run cleanly instead of crashing on an uncaught BaseException.

Controller-reported operation failures and undecodable payloads now raise the recoverable type; contract/protocol violations keep the fatal type. No changes to the generic tool-calling loop are required — both types plug into the existing fatal/recoverable handling.

DesktopAgentOsError subclasses AutomationError (from models/exceptions.py) rather than AgentError; the latter would introduce a circular import, while the former is cycle-safe.

Testing

  • Added a regression test that drives both error types through the tool-calling loop: the recoverable one returns an is_error=True tool result, the fatal one propagates.
  • Updated the existing decode test to expect the recoverable type for undecodable file contents.
  • pdm run qa:fix passes (typecheck, format, lint); affected unit suites pass.

🤖 Generated with Claude Code

Reading a remote file or directory that does not exist raised a
DesktopAgentOsError that inherited from BaseException, so the tool-calling
loop's `except Exception` handler never caught it. The error propagated all
the way up and crashed the run instead of being surfaced to the agent as a
tool error result, as recoverable tool failures are everywhere else.

Introduce two error types that map onto the existing fatal/recoverable
handling in the tool-calling loop:

- DesktopAgentOsException (recoverable): a plain Exception for failures the
  agent can work around (path not found, undecodable file contents). The
  loop's generic `except Exception` catches it and returns it to the agent.
- DesktopAgentOsError (unfixable): now inherits from AutomationError for
  protocol violations (unexpected response type, missing error and response).
  The loop's existing `except (AgentError, AutomationError): raise` re-raises
  it, terminating the run cleanly instead of crashing on an uncaught
  BaseException.

Controller operation failures (res.error) and undecodable payloads now raise
the recoverable type; contract violations keep the fatal type. No changes to
the generic tool-calling loop are required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@philipph-askui
philipph-askui merged commit 69b4cca into main Aug 13, 2026
1 check passed
@philipph-askui
philipph-askui deleted the fix/desktop-agent-os-recoverable-exception branch August 13, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants