JSON envelope and exit codes
The --json envelope every command prints, and what each exit code means.
Every command with --json prints exactly one object to stdout. Field
names are stable — new fields only ever get added.
{
"v": 1,
"ok": true,
"command": "click",
"tab": "t_3f9a",
"profile": "default",
"revision": 7,
"prev_revision": 6,
"executor": "bridge",
"executor_detail": { "adapter": "compat-bridge/chromiumoxide", "adapter_version": "0.1.1+chromiumoxide.0.9.1", "mode": "local", "fidelity": "reduced" },
"result": {},
"diff": {},
"timing": { "total_ms": 412, "daemon_ms": 398, "executor_ms": 371 },
"trace_id": "tr_01J...",
"warnings": []
}
On error, ok is false, result and diff are omitted, and an
error object appears instead:
{
"v": 1, "ok": false, "command": "click", "tab": "t_3f9a", "revision": 9,
"executor": "none",
"error": {
"code": "E_STALE_ID",
"message": "element 48 (revision 6) no longer matches a single element; the page is now at revision 9",
"retryable": true,
"details": { "id": 48, "id_revision": 6, "current_revision": 9, "reason": "fingerprint_no_match", "candidates": [], "hint": "run `jawb observe` and retry with a current id" }
},
"timing": { "total_ms": 12 }, "trace_id": "tr_01J..."
}
executorisnative,bridge,daemon(pure session bookkeeping), ornone(failed before dispatch). This — plus the trace — is the only place jawb discloses which engine ran your command; there's no separate first-use notice.revisionis the tab's observation revision after the command. Tab-less commands omit it.diffis present on every Act command and on navigation commands.retargetedappears on a success envelope when the daemon resolved your target ID by fingerprint to a rebuilt element:"retargeted": { "from": 48, "to": 97, "revision": 9 }.
Exit codes
| Exit | Meaning |
|---|---|
| 0 | ok |
| 1 | generic or internal failure (E_INTERNAL, E_NAVIGATION_FAILED, E_FETCH_FAILED, E_DOCTOR_FAILED) |
| 2 | usage or target error (E_USAGE, E_NOT_FOUND, E_UNKNOWN_ID, E_NO_MATCH, E_AMBIGUOUS, E_NO_TAB, E_UNKNOWN_TAB, E_UNKNOWN_PROFILE, E_PROFILE_EXISTS) |
| 3 | daemon unreachable or unauthorized (E_DAEMON_UNREACHABLE, E_UNAUTHORIZED, E_VERSION_MISMATCH) |
| 4 | page state (E_STALE_ID, E_NOT_ACTIONABLE) — retryable after observe |
| 5 | policy (E_POLICY_DENIED, E_CONFIRMATION_REQUIRED) |
| 6 | capability unavailable (E_BRIDGE_DISABLED, E_NOT_IMPLEMENTED, E_BRIDGE_UNAVAILABLE, E_VAULT_UNAVAILABLE) |
| 7 | E_TIMEOUT |
E_STALE_ID.details.reason is one of fingerprint_no_match,
fingerprint_ambiguous, expired. E_NOT_ACTIONABLE.details.reason is
one of hidden, disabled, covered, detached, not_editable,
outside_viewport_unscrollable.