#1505·zx

`ProcessOutput.json()` parses combined stdout+stderr, breaking on CLIs that log progress to stderr

Author: infomihoCreated Aug 19, 2026Updated Sep 4, 2026

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, 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?

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