Skip to content

fix(forge): handle BrokenPipe in non-TTY reporter & shell writes#14215

Closed
o-az wants to merge 1 commit into
masterfrom
o-az/fix/broken-pipe-tee
Closed

fix(forge): handle BrokenPipe in non-TTY reporter & shell writes#14215
o-az wants to merge 1 commit into
masterfrom
o-az/fix/broken-pipe-tee

Conversation

@o-az
Copy link
Copy Markdown
Contributor

@o-az o-az commented Apr 9, 2026

Piping forge output to tee crashes with a BrokenPipe panic. Some
widely-deployed tee implementations (uutils-coreutils <= 0.8, default
on NixOS and common via Homebrew) close the read end of the pipe during
write pauses like Solc compilation, causing println!() in
BasicStdoutReporter to abort.

Replace BasicStdoutReporter with SafeStdoutReporter that treats
BrokenPipe as non-fatal in all reporter callbacks. Also handle
BrokenPipe in the shared shell stdout/stderr write paths.

Repro:

tmpdir="$(mktemp -d)"
cd "$tmpdir"
forge init --quiet
forge build | tee out.log

Before: exit 134 (SIGABRT/panic)
After: exit 0, command completes normally

@o-az o-az force-pushed the o-az/fix/broken-pipe-tee branch from 51c08af to aa146eb Compare April 9, 2026 10:04
@o-az o-az changed the title fix(forge): handle BrokenPipe in non-TTY reporter and shell writes fix(forge): handle BrokenPipe in non-TTY reporter & shell writes Apr 9, 2026
zerosnacks added a commit to foundry-rs/compilers that referenced this pull request Apr 9, 2026
Piping compiler output to `tee` crashes with a `BrokenPipe` panic. Some
widely-deployed `tee` implementations (uutils-coreutils ≤ 0.8, default
on NixOS and common via Homebrew) close the read end of the pipe during
write pauses (e.g. during Solc compilation), causing `println!()` in
`BasicStdoutReporter` to abort.

Replace `println!`/`eprintln!` with a `write_line` helper that treats
`BrokenPipe` as non-fatal. Non-`BrokenPipe` errors still panic,
preserving the prior behavior.

## Repro

```bash
tmpdir="$(mktemp -d)"
cd "$tmpdir"
forge init --quiet
forge build | tee out.log
```

Before: exit 134 (SIGABRT/panic)
After: exit 0

## Changes

- Replace `println!`/`eprintln!` in `BasicStdoutReporter` with
`write_line()` helper
- `write_line()` silently discards `BrokenPipe`, panics on other I/O
errors
- Add tests for BrokenPipe, non-BrokenPipe, and newline-terminated
output

## Context

This is the upstream fix for
[foundry-rs/foundry#14215](foundry-rs/foundry#14215),
which works around this issue by duplicating `BasicStdoutReporter` as
`SafeStdoutReporter` in foundry. Fixing it here eliminates the need for
a downstream copy.

Prompted by: zerosnacks

---------

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
@zerosnacks
Copy link
Copy Markdown
Contributor

Hey @o-az, thanks for the PR!

Fixed directly in foundry-rs/compilers#367, supersedes this PR I believe; your PR has some additional handling w/ write_all_best_effort critical but I'm not sure if it is really necessary w/ the fix in place.

Will soon create a release for foundry-compilers and include it in a nightly release

@zerosnacks zerosnacks closed this Apr 9, 2026
@github-project-automation github-project-automation Bot moved this to Done in Foundry Apr 9, 2026
@o-az o-az deleted the o-az/fix/broken-pipe-tee branch April 14, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants