Skip to content

fix(pty): stabilize non-ASCII output round-trip test - #12848

Merged
marius-kilocode merged 1 commit into
mainfrom
fix-pty-non-ascii-flake
Aug 4, 2026
Merged

fix(pty): stabilize non-ASCII output round-trip test#12848
marius-kilocode merged 1 commit into
mainfrom
fix-pty-non-ascii-flake

Conversation

@marius-kilocode

@marius-kilocode marius-kilocode commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Problem

The pty > round-trips non-ASCII output byte-identically test intermittently fails on the macOS unit CI job with a 15s timeout waiting for café-über-北京-🚀. Previous mitigations (bumping the wait timeouts, feeding replayed output into the wait helper, and switching the fixture to raw octal escapes) made the test slower or more tolerant without removing the underlying race, so it kept flaking.

Root cause

The fixture command prints the marker and exits immediately:

sh -c "printf 'caf\303\251-...-🚀\n'"

The Bun runtime PTY driver (packages/core/src/pty/pty.bun.ts, backed by bun-pty) bridges a Rust reader thread to the JS event loop. The Rust side emits Msg::Data chunks and, once the child exits, Msg::End. When the JS read loop observes Msg::End, the Rust Reader waits only 20ms for trailing data before reporting child exit; anything the reader thread pushes later is discarded.

On a loaded CI runner the reader thread can be scheduled more than 20ms behind the wait-thread that signals the child exit, so the final output bytes never reach the test. This test's marker sits at the very end of the output, so waitForOutput runs out its 15s timeout. The flake hits this test and not its siblings because every sibling either keeps the child alive after printing (printf ...; sleep 5) or has no output that can be lost.

Fix

Keep the child alive until the test is torn down, matching the sibling preserves explicit command arguments test:

printf 'caf\303\251-...-🚀\n'; sleep 5

While the child is alive no Msg::End is produced, so the output is always fully consumed before the process can exit and the race window cannot exist. Teardown already kills the process group (Pty.remove -> KiloPtyTermination), so the test still completes in milliseconds and leaks no processes. The byte-identity assertion is unchanged; only the exit timing is decoupled from output delivery, which the test never meant to be sensitive to.

waitForOutput now includes the received output in its timeout error, so any future failure is self-diagnosing (for example a truncated tail shows exactly which bytes were dropped).

Why this is not flaky anymore

  • By construction: output is drained while the child is alive, so there is no exit event to race against.
  • The fixed test passed 40/40 iterations under sustained load (the full core suite looped concurrently) at which sibling pty tests produced 15s-timeout flakes.
  • The sibling test using the same sleep 5 pattern has never flaked since these tests were introduced.

CI verification

The first CI attempt's macOS unit job failed on an unrelated, pre-existing flake (v2 pty HttpApi > applies plugin shell environment before forced PTY values, a different test in the CLI package that already uses sleep 5 and a 30s timeout). It passed on re-run, and the full workflow is green with this fix in place.

The round-trips non-ASCII output test printed the fixture and exited
immediately. On loaded CI runners bun-pty can observe the child-exit End
message before its reader thread has drained the last output bytes, dropping
the trailing UTF-8 marker and timing the test out.

Keep the child alive after printing (printf ...; sleep 5), matching the
sibling explicit-arguments test, so output is fully consumed before the
process can exit. Also include the received output in the waitForOutput
timeout error to make any future failure self-diagnosing.
@marius-kilocode
marius-kilocode marked this pull request as ready for review August 4, 2026 10:22
@kilo-code-bot

kilo-code-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 file)
  • packages/core/test/pty/pty-session.test.ts

Reviewed by kimi-k3 · Input: 88K · Output: 5K · Cached: 290.7K

Review guidance: REVIEW.md from base branch main

@marius-kilocode
marius-kilocode merged commit 849f92e into main Aug 4, 2026
38 of 42 checks passed
@marius-kilocode
marius-kilocode deleted the fix-pty-non-ascii-flake branch August 4, 2026 11:11
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
fix(pty): stabilize non-ASCII output round-trip test
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.

2 participants