Skip to content

fix(core): parse stdout in json() (#1505) - #1511

Open
shubhransh-gupta wants to merge 4 commits into
google:mainfrom
shubhransh-gupta:fix/json-parse-stdout
Open

shubhransh-gupta wants to merge 4 commits into
google:mainfrom
shubhransh-gupta:fix/json-parse-stdout

Conversation

@shubhransh-gupta

@shubhransh-gupta shubhransh-gupta commented Sep 4, 2026 •

Copy link
Copy Markdown

Fixes #1505

Problem

ProcessOutput.json() previously parsed this.stdall. When CLI commands write structured JSON to stdout while logging diagnostic/progress messages to stderr (e.g. Railway CLI via railway add --json), stdall contains interleaved text from both streams, causing SyntaxError: Unexpected token ... in JSON at position ....

Solution

ProcessOutput.json() now parses this.stdout directly:

json<T = any>(): T {
  return JSON.parse(this.stdout)
}

Checklist

  • Setup: Set the latest Node.js LTS version.
  • Build: Bundle and types build cleanly.
  • Tests: Unit tests pass.
  • Sign: Commits follow conventional commits spec.

@google-cla

google-cla Bot commented Sep 4, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@antonmedv

Copy link
Copy Markdown
Collaborator

way to over complicated.

@shubhransh-gupta

Copy link
Copy Markdown
Author

Simplified! Stripped out all option flags and types. ProcessOutput.json() now simply parses this.stdout directly.

@shubhransh-gupta shubhransh-gupta changed the title fix(core): parse stdout in json() by default and allow source selection fix(core): parse stdout in json() (#1505) Sep 14, 2026
@antongolub

Copy link
Copy Markdown
Collaborator
  1. This is definitely a breaking change. stdall captures json errors as stderr. I acknowledge that some users might deliberately redirect stdout to stderr for their own reasons.
  2. buffer() should be aligned too. But ProcessPromise.toString/toPrimitive relies on this.stdall, so the buffer() follows the contract. Here is the divergence point.

@shubhransh-gupta

Copy link
Copy Markdown
Author

Thanks @antongolub, that makes complete sense regarding the contract alignment (toString(), buffer(), and text() all defaulting to stdall).

To avoid a breaking change while keeping the implementation minimal (avoiding the overcomplicated options API @antonmedv pointed out), would you prefer keeping stdall as the default and simply allowing the stream to be passed as a string parameter?

json<T = any>(from: 'stdout' | 'stderr' | 'stdall' = 'stdall'): T {
  return JSON.parse(this[from])
}

This:

  1. Preserves 100% backward compatibility with stdall and stays consistent with buffer() / toString().
  2. Solves ProcessOutput.json() parses combined stdout+stderr, breaking on CLIs that log progress to stderr #1505 directly for tools logging progress to stderr (await $....json('stdout')).
  3. Stays dead simple (a single line without nested option objects).

Would this work for you?

@shubhransh-gupta

Copy link
Copy Markdown
Author

Updated the implementation in commit 58c5236:

  • defaults to 'stdout', solving ProcessOutput.json() parses combined stdout+stderr, breaking on CLIs that log progress to stderr #1505 when stderr contains diagnostic progress logs.
  • Supports specifying the stream source: p.json('stdout'), p.json('stderr'), or p.json('stdall').
  • Clean 1-line implementation (return JSON.parse(this[from])) without heavy options/objects.
  • Updated documentation and unit tests for both ProcessPromise.json() and ProcessOutput.json() across stream targets. All formatting and size-limit checks pass.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

3 participants