Skip to content

fix(cli): don't truncate --format json output through a pipe - #281

Open
DanMat wants to merge 1 commit into
arethetypeswrong:mainfrom
DanMat:fix/json-pipe-truncation
Open

DanMat wants to merge 1 commit into
arethetypeswrong:mainfrom
DanMat:fix/json-pipe-truncation

Conversation

@DanMat

@DanMat DanMat commented Aug 19, 2026

Copy link
Copy Markdown

Closes #279 (a recurrence of #184)

--format json output is truncated when stdout is a pipe and the exit code is non-zero. Two root causes, both fixed here:

  1. write() resolved on the source Readable's end event, not on stdout draining — out.write()'s return value was ignored, so it resolved with bytes still buffered. It now uses out.write(data, callback) and resolves when the chunk is actually handled, delivering the flush its comment promises.
  2. The JSON branch then called process.exit(exitCode), terminating before a buffered pipe finishes flushing. It now sets process.exitCode and returns, matching the human-readable branch (which already worked for exactly this reason).

Added a regression test for write() that fails on the old implementation and passes on the new one. Changeset included (patch).

Verified: full cli suite (31 tests, incl. the existing -f json snapshot) passes; prettier + tsgo clean.

Written with AI assistance; I've reviewed and tested the change and will maintain it.

The JSON branch called process.exit() after writing, which could
terminate before a buffered stdout pipe finished flushing, truncating
the output when the exit code was non-zero (arethetypeswrong#279, a recurrence of arethetypeswrong#184).

- write() now resolves once stdout has actually handled the data (via the
  write callback) instead of when the source string is exhausted, so it
  delivers the flush its comment promises.
- the JSON branch sets process.exitCode and returns, matching the
  human-readable branch, rather than calling process.exit().

Adds a regression test for write().
@changeset-bot

changeset-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5d03a30

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@arethetypeswrong/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@DanMat

DanMat commented Aug 19, 2026

Copy link
Copy Markdown
Author

Reproduced the truncation locally and confirmed the fix. Fixture: a failing package with 17 entrypoints (≈311 KB of --format json output), piped through cat:

Before (base main):

$ attw pkg.tgz --profile esm-only --format json | cat | wc -c
131072        # stops at a pipe-buffer boundary — JSON.parse() fails (truncated)

After (this PR):

$ attw pkg.tgz --profile esm-only --format json | cat | wc -c
311241        # complete — JSON.parse() succeeds

Writing to a file (> out.json) yields the full 311,241 bytes on both, so the truncation is governed by the pipe + non-zero exit, exactly as described in #279. The 131072 here is 2×64 KiB; the exact boundary varies by platform, the mechanism doesn't.

The added unit test also fails on the base write() implementation and passes with the fix.

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.

--format json still truncated through a pipe when the exit code is non-zero (#184)

1 participant