Exit codes
Twenty-six classes, plus a timeout that is not a failure.
Every failure returns a nonzero exit status, a concise message on stderr, and — with --json — a structured error carrying a stable code.
Exit statuses are stable and are part of the interface. Branch on the status or the code, never on the message.
| Exit | Code | Meaning |
|---|---|---|
| 1 | internal_error | Unexpected internal failure. |
| 2 | invalid_arguments | Unparsable or contradictory arguments. |
| 3 | display_unavailable | The X11 display could not be opened. |
| 4 | invalid_region | Region is malformed, zero sized, or out of bounds. |
| 5 | window_not_found | The requested window does not exist. |
| 6 | capture_failed | The backend could not produce a frame. |
| 7 | resize_failed | The requested resize could not be performed. |
| 8 | encode_failed | PNG or JPEG encoding failed. |
| 9 | output_failed | Writing the result failed. |
| 10 | incompatible_frames | The two frames cannot be compared. |
| 11 | comparison_failed | The comparison could not be performed. |
| 12 | image_load_failed | An input image could not be read or decoded. |
| 13 | geometry_changed | The observed target changed shape or moved. |
| 14 | target_lost | The observed target disappeared. |
| 15 | invalid_duration | A duration was zero, negative, or unparsable. |
| 16 | observation_failed | The observation could not be performed. |
| 17 | session_not_found | The session is not registered — closed, or the service restarted. |
| 18 | session_busy | The session is running an observation; a second one, or a close, was refused. |
| 19 | session_closed | The session has been closed. |
| 20 | frame_not_available | The requested frame ID is not retained, or was never captured. |
| 21 | no_frame_available | The session has not captured any frame yet. |
| 22 | service_unavailable | No `eensh serve` could be reached at the socket path. |
| 23 | service_protocol_error | The service could not decode a request, or a protocol version was refused. |
| 24 | service_overloaded | The service refused work to preserve freshness. |
| 25 | invalid_presentation_policy | The presentation policy is malformed or self-contradictory. |
| 26 | payload_budget_exceeded | The required views cannot fit in the requested budget, even at their floors. |
| 100 | — | Timeout: the observation ran, the condition did not occur. |
Errors cross the process boundary unchanged
A service error is mapped back to the status it would have had on the standalone path. A frame_not_available from a session exits 20, exactly as the standalone equivalent would — so this table stays a single source of truth whether or not a service is involved.
For the grouped-by-decision view, with notes on how to react to each class, see errors that guide you.
Presentation additions
Two codes were added with the presentation layer, and both are caller errors rather than environmental ones:
25 invalid_presentation_policy— a malformed or self-contradictory policy: a zero-sized region, a duplicate region name, a region namedoverview, or a policy requesting no image at all. Refused before any capture is attempted.26 payload_budget_exceeded— a budget that cannot hold the required views. The message quotes the smallest achievable payload, so the caller has a number to work up from.