fix: Write error JSON envelope to stdout, not stderr#45
Conversation
The CLI contract states stdout is always the JSON envelope (success or error); stderr is reserved for diagnostics. Agents parsing stdout saw empty output on failures because the error envelope was written to stderr. Always write the rendered output to stdout regardless of exit code. The exit code still communicates success/failure to the shell, and the envelope's error field communicates it to JSON consumers. Fixes: DEVEX-697 Co-authored-by: Cursor <cursoragent@cursor.com>
Standardizes PR descriptions with a Summary, Test plan, and Manual verification section that guides reviewers through testing with and without the change using a local cli-engine path override. Co-authored-by: Cursor <cursoragent@cursor.com>
|
I really like that you are adding a pull request template, thanks for that. Although this gap was identified, I'm not sure we actually want this. IMO the more common pattern is for errors to go to stderr, successful output to stdout. |
|
@copilot what are your thoughts on this? Is this change a best practice for a CLI? |
Good question — there's a genuine tension here, and both conventions have merit. The traditional UNIX argument (errors → stderr): The structured-output argument (errors → stdout): My take: That said, I recognize this is a design-level call that sits with the team. If the preference is to stay consistent with the broader UNIX/AWS CLI convention — errors to stderr, success to stdout — I'm happy to revert the change. Just let me know. |
Summary
stderr remains reserved for diagnostics only (tracing, update notices, fatal framework errors).
Test plan
cargo fmt --all --checkcargo clippy --all-targets -- -D warningsRUSTDOCFLAGS='-D warnings' cargo doc --no-depscargo test --all-targetscargo test --docManual verification
Requires the godaddy/cli repo to build a binary against this branch.
Setup (one-time):
Test WITHOUT the fix (baseline):
Test WITH the fix:
Cleanup: revert rust/Cargo.toml back to the published version before committing.