Problem
openclaw agent --json --deliver currently has no machine-readable indication of whether delivery succeeded, failed, or was skipped. The JSON envelope contains payloads and meta but no delivery status.
This means automation consuming --json output cannot detect silent delivery failures — the exact scenario that #53961 adds diagnostic logging for in non-JSON mode.
Desired behavior
Add a deliveryStatus field to the JSON output envelope when --deliver is used:
{
"payloads": [...],
"meta": {...},
"deliveryStatus": {
"requested": true,
"attempted": true,
"succeeded": false,
"error": true
}
}
Design considerations
The JSON envelope is currently emitted before delivery (so stdout stays machine-readable even if delivery throws). Adding deliveryStatus requires either:
- Deferring JSON output until after delivery — but then late throws (non-bestEffort API timeouts) would skip JSON output entirely, breaking scripts
- Emitting two JSON objects — payload first, status second — but this changes the single-object contract
- Wrapping delivery in try/finally to ensure JSON is always emitted, with status reflecting the outcome
- Separate status line — a second JSON line (JSONL-style) with just the delivery result
Each approach has trade-offs around backward compatibility, error handling, and parseability. Needs design discussion before implementation.
Additional edge cases to address
- Partial best-effort delivery (some payloads succeed, others fail)
- No-payload runs (tool-only turns, heartbeat acks) where delivery is requested but nothing to send
normalizeAgentCommandReplyPayloads() intentionally dropping silent-only payloads
Context
Related: #53961 (adds non-JSON diagnostic logging for silent delivery failures). The deliveryStatus object is already returned in the function's in-process return value — this issue is specifically about surfacing it in the stdout JSON output.
Problem
openclaw agent --json --delivercurrently has no machine-readable indication of whether delivery succeeded, failed, or was skipped. The JSON envelope containspayloadsandmetabut no delivery status.This means automation consuming
--jsonoutput cannot detect silent delivery failures — the exact scenario that #53961 adds diagnostic logging for in non-JSON mode.Desired behavior
Add a
deliveryStatusfield to the JSON output envelope when--deliveris used:{ "payloads": [...], "meta": {...}, "deliveryStatus": { "requested": true, "attempted": true, "succeeded": false, "error": true } }Design considerations
The JSON envelope is currently emitted before delivery (so stdout stays machine-readable even if delivery throws). Adding
deliveryStatusrequires either:Each approach has trade-offs around backward compatibility, error handling, and parseability. Needs design discussion before implementation.
Additional edge cases to address
normalizeAgentCommandReplyPayloads()intentionally dropping silent-only payloadsContext
Related: #53961 (adds non-JSON diagnostic logging for silent delivery failures). The
deliveryStatusobject is already returned in the function's in-process return value — this issue is specifically about surfacing it in the stdout JSON output.