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..."
}
  • executor is native, bridge, daemon (pure session bookkeeping), or none (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.
  • revision is the tab's observation revision after the command. Tab-less commands omit it.
  • diff is present on every Act command and on navigation commands.
  • retargeted appears 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

ExitMeaning
0ok
1generic or internal failure (E_INTERNAL, E_NAVIGATION_FAILED, E_FETCH_FAILED, E_DOCTOR_FAILED)
2usage 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)
3daemon unreachable or unauthorized (E_DAEMON_UNREACHABLE, E_UNAUTHORIZED, E_VERSION_MISMATCH)
4page state (E_STALE_ID, E_NOT_ACTIONABLE) — retryable after observe
5policy (E_POLICY_DENIED, E_CONFIRMATION_REQUIRED)
6capability unavailable (E_BRIDGE_DISABLED, E_NOT_IMPLEMENTED, E_BRIDGE_UNAVAILABLE, E_VAULT_UNAVAILABLE)
7E_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.