`ProcessOutput.json()` parses combined stdout+stderr, breaking on CLIs that log progress to stderr
- Dominant language
- JavaScript
- Stars
- 45.7k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
### What happened?
`ProcessOutput.json()` runs `JSON.parse` on the combined output (`stdall`), not on stdout. Well-behaved CLIs write JSON to stdout and progress/prompts to stderr, so the stderr output gets mixed in and `json()` throws even though stdout contains valid JSON.
We hit this in [Wasp](https://github.com/wasp-lang/wasp), where we orchestrate the Railway CLI with its `--json` flag: `railway add --json` prints the JSON result to stdout but echoes the prompt answers to stderr, so `.json()` broke unexpectedly. We had to resort to parsing stdout ourselves with `JSON.parse(output.stdout)`: https://github.com/wasp-lang/wasp/pull/4711
### How it should work?
`json()` should parse stdout only. If the combined behavior is intentional, it would help to document which stream `json()` reads and offer a stdout-only variant e.g. `json({ source: 'stdout' })`
### How to reproduce the bug?
```js
import { $ } from 'zx'
const out = await $({ quiet: true })`node -e "console.error('progress...'); console.log('{\\"ok\\":true}')"`
JSON.parse(out.stdout) // { ok: true }
out.json() // SyntaxError: Unexpected token 'p', "progress.."... is not valid JSON
```
### Version
8.3.2
### What's OS kind?
Mac
Contributor guide
Research direction
Start at the ProcessOutput.json() implementation and run the supplied Node.js reproduction with stderr progress and JSON on stdout. Trace which output stream the method parses; done means valid stdout JSON parses successfully even when stderr contains progress text, with coverage for the reproduced case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100