You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
vp run -r <task> aborts with Failed to forward task process output: Resource temporarily unavailable (os error 11) (Linux, GitHub Actions) or os error 35 (macOS), then kills the other running tasks (exit 137). No test fails; the run is lost because output forwarding hit EAGAIN.
This is the same root cause as #2165. The fix there (#2173, ensureBlockingStdio() at startup) is present in our version, but it clears O_NONBLOCK only once. The flag gets set again mid-run on the shared stdout description, and the task-output forwarding path does not handle WouldBlock.
What we observed
We sampled os.get_blocking(1) every 50–200 ms from a sibling process sharing the same stdout pipe, with a deliberately slow reader (… | (sleep 25; cat)):
Run
Non-blocking windows on the shared stdout
vp run -r test, full workspace
0.1–0.3 s, then 25.4–28.6 s, even when invoked as ./node_modules/.bin/vp (no package manager in between)
vp run --filter <pkg> test, where test is a package.json script running playwright test
1.4–4.5 s
playwright test on its own
0.4–3.6 s
The mid-run window appears when the reader starts draining a full pipe. That points at Node re-marking its non-TTY stdout non-blocking under backpressure. Any ForwardTaskProcessOutput write landing in that window fails with EAGAIN.
Uncached tasks make it worse. vite-task runs them with inherited stdio (crates/vt/src/session/execute/mod.rs: Uncached { pipe_writers: None } => SpawnStdio::Inherited), so a Node child such as Playwright marks the shared description non-blocking for seconds while other tasks' captured output is being forwarded.
A regular-file sink never fails (vp run -r test > out.log), which is consistent with EAGAIN on the write side.
Reproduction
A workspace with several vp test tasks producing a few thousand lines of output, plus one package whose test is a package.json script (uncached, so it inherits stdio) running a Node tool, for example playwright test.
Run with a stdout consumer that lags:
vp run -r test2>&1| (sleep 25; cat > /dev/null)
vp run --last-details
The details show one task with ✗ Error: Failed to forward task process output: Resource temporarily unavailable (os error 35) and the rest ✗ (exit code: 137).
On GitHub Actions it reproduced on 2 of 2 runs for one change set, and passed once we removed one test task from the run, which changed the task schedule. That makes it timing dependent, and silent until it isn't.
Versions
vite-plus 0.2.9, which already calls ensureBlockingStdio() in dist/bin.js.
Node 24.21, macOS 26.5 (arm64) and GitHub Actions ubuntu-24.04-arm.
We have not run 0.3.x or 1.0.0-rc.0, but vite-taskmain (8dd41bc8) has no WouldBlock handling in pipe_stdio / ForwardTaskProcessOutput. fix(cli): handle broken pipes in command output #2785 adds a retrying writer only for --version and env list-remote.
Alternatively, or as well, re-assert blocking mode on the sinks before writing. Clearing it once at startup cannot cover Node re-marking the description later, or inherited children marking it.
Workaround
Send vp's output to a regular file in CI and print it afterwards (vp run -r test > log 2>&1; rc=$?; cat log; exit $rc).
Describe the bug
vp run -r <task>aborts withFailed to forward task process output: Resource temporarily unavailable (os error 11)(Linux, GitHub Actions) oros error 35(macOS), then kills the other running tasks (exit 137). No test fails; the run is lost because output forwarding hitEAGAIN.This is the same root cause as #2165. The fix there (#2173,
ensureBlockingStdio()at startup) is present in our version, but it clearsO_NONBLOCKonly once. The flag gets set again mid-run on the shared stdout description, and the task-output forwarding path does not handleWouldBlock.What we observed
We sampled
os.get_blocking(1)every 50–200 ms from a sibling process sharing the same stdout pipe, with a deliberately slow reader (… | (sleep 25; cat)):vp run -r test, full workspace./node_modules/.bin/vp(no package manager in between)vp run --filter <pkg> test, wheretestis apackage.jsonscript runningplaywright testplaywright teston its ownForwardTaskProcessOutputwrite landing in that window fails withEAGAIN.crates/vt/src/session/execute/mod.rs:Uncached { pipe_writers: None } => SpawnStdio::Inherited), so a Node child such as Playwright marks the shared description non-blocking for seconds while other tasks' captured output is being forwarded.vp run -r test > out.log), which is consistent withEAGAINon the write side.Reproduction
vptest tasks producing a few thousand lines of output, plus one package whosetestis apackage.jsonscript (uncached, so it inherits stdio) running a Node tool, for exampleplaywright test.✗ Error: Failed to forward task process output: Resource temporarily unavailable (os error 35)and the rest✗ (exit code: 137).On GitHub Actions it reproduced on 2 of 2 runs for one change set, and passed once we removed one test task from the run, which changed the task schedule. That makes it timing dependent, and silent until it isn't.
Versions
vite-plus0.2.9, which already callsensureBlockingStdio()indist/bin.js.ubuntu-24.04-arm.vite-taskmain(8dd41bc8) has noWouldBlockhandling inpipe_stdio/ForwardTaskProcessOutput. fix(cli): handle broken pipes in command output #2785 adds a retrying writer only for--versionandenv list-remote.Suggested fix
WouldBlockin the forwarding writer (poll the fd for writability, then retry), like theprint_and_flushhelper from fix(cli): handle broken pipes in command output #2785, rather than treatingEAGAINas fatal.Workaround
Send
vp's output to a regular file in CI and print it afterwards (vp run -r test > log 2>&1; rc=$?; cat log; exit $rc).Related: #2165, #2173, #2169, #2785.