JSON output and exit codes

Human vs --json

Mode stdout stderr
Default One or more human summary lines Errors only
--json Single JSON value (success or failure) --insecure warnings only

Success JSON is the SDK data object — the same shape as HealthData.to_wire(), PlanData, BulkResult, etc. It is not the HTTP envelope ({ "ok": true, "data": … }).

Full per-command examples: CLI reference (human line, JSON sample, jq). Machine-readable catalog: response_samples.json.

Examples

Health:

eve-iac health --json
# {"status": "ok", "tls": true, "version": "0.9.0-1"}

eve-iac health --json | jq -r .status

Plan then live-safe reconcile. Do not gate on .applicable — that field is a summary of immediate full convergence. Partial / pending_stop is a valid first pass.

plan=$(eve-iac plan ./IaC/demo --json)
identity=$(jq -r .plan_identity <<<"$plan")
# Live-safe: omitted --yes applies live_applicable work and returns remaining plan_identity.
eve-iac reconcile ./IaC/demo --json --plan-identity "$identity"
# If remaining work is requires_stop, a second call with --yes AND the returned identity:
# eve-iac --yes reconcile ./IaC/demo --json --plan-identity "$identity"
# --yes does not invent identity. Omitted identity while stop remains → 409 plan_stale, exit 10, zero StopNode.

Lifecycle exec — fail CI when nodes did not start:

eve-iac exec ./IaC/demo start --json | jq -e '.failed + .invalid == 0'

Load (local, no agent):

eve-iac load /Customers/OSPF.unl --json | jq -r .project

Failure JSON

With --json, CLI and agent errors still write JSON to stdout (exit code ≠ 0):

{
  "error": "unauthenticated",
  "code": "unauthenticated",
  "status": 401
}

Parse with jq -r .code in CI. Do not rely on the error string alone.

SDK parity

CLI --json Python TypeScript Go
Success object Return value of client.method(...) await client.method(...) data, err := client.Method(...)
Failure AgentError (not printed unless caught) rejected AgentError non-nil error

See Python examples — Working with responses and each method’s JSON wire shape / Processing the result in the API reference.

Human login omits the token. --json login includes token — store as EVE_IAC_TOKEN; do not echo in CI logs.

Exit codes

Verified from cli/eveiac_cli/exitcodes.py and agent_exit_code():

Code Meaning
0 Success
1 Local error (missing URL, invalid lab, packing)
2 Usage (bad flags / invalid prune+from_eve / LOAD mode forbidden command)
3 Authentication (AgentError auth codes or HTTP 401)
4 TLS (code starting with tls_ or known TLS codes)
5 Confirmation required (--yes missing)
10 Other agent error (HTTP 400/409 including plan_stale / config_conflict; remaining requires_stop without --yes --plan-identity)

Use set -e plus explicit checks on 5 if a job might hit destroy/wipe without --yes. 409 plan_stale is exit 10, not 5. --json preserves code on stdout.

eve-iac destroy ./lab --json; ec=$?
case $ec in
  0) ;;
  5) echo "needs --yes" >&2; exit 5 ;;
  *) exit $ec ;;
esac