Code page test results

Results of T1 to T6 in the plan, run at code pages 932 and 437 with Bun 1.4.3, Bun canary, Node.js and Deno. Each harm caused by Bun changing the console code page is shown by measurement, and every result links to its evidence file

📅 Created: 2026-10-04 / Updated: 2026-10-17

Key points

  1. Bun switches the console to code page 65001 at startup, and restores the value it saved at exit. The code page belongs to the console and is shared by every process attached to it. Source: init() (output.rs lines 561 to 567) and restore() (output.rs lines 517 to 524). Evidence, the code page while Bun runs: 932 / 437 (T1)
  2. Two Bun processes in one console overwrite each other's saved value. Output is garbled, 65001 is left on the console, and other programs in the same console break. Evidence: garbled screen 932 / 437 (T5), broken neighbor 932 / 437 (T4), forced kill 932 / 437 (T3)
  3. PR #43662, the open fix for bun#43660, does not remove the cause. It fixes console.log output, but Bun still switches the console to 65001 while it runs (932 / 437), a forced kill still leaves 65001 (932 / 437), fs.writeSync(1), fs.write(1) and Bun.write(Bun.stdout) are still garbled (932 / 437), and restoring still loses a race now and then when the order is not fixed (timeline)
  4. Node.js and Deno never change the code page and print correctly in every case: Node.js 932 / 437, Deno 932 / 437 (T1)

Request (bun#44693): do not change the console code page at all, and write all console output with WriteConsoleW. Every verdict was the same whether the console started at 932 (Japanese Windows) or 437 (English Windows). The details follow in Conclusion; how the tests were run is in Conditions.

Conclusion

Bun switches the console input and output code pages to 65001 the moment it starts (before any script code runs), and on exit restores "the value it saved at start". This alone causes every harm H1 to H7 in the plan. Node.js and Deno never changed the code page and behaved correctly in every case.

The rows are in order of importance: the harms that remain even with PR #43662 come first.

HarmDescriptionBun, canaryBun PR #43662Node.js, DenoEvidence (932 / 437)
H4Other processes in the same console are affected❌ happens❌ still happens: the console is at 65001 while Bun runs, and after a forced kill✅ neverscreen / screen (T4: the neighbor script is garbled and chcp shows 65001); PR: log / log (T1, 65001 while running)
H6A forced kill leaves the code page changed❌ happens❌ still happens✅ neverlog / log (T3); PR: screen / screen
H1The output of a piped peer is garbled❌ happens⚠️ fixed for console.log and process.stdout; still happens with fs.writeSync(1), fs.write(1) and Bun.write(Bun.stdout)✅ neverscreen / screen (T5 ww); PR: screen / screen (T5 ww with fs.writeSync)
H5After the code page is put back to the starting value, Bun writes raw UTF-8 bytes and they are garbled❌ happens⚠️ same as H1✅ neverlog / log (T5 ww: the reader's code page right before writing is the starting value)
H365001 is left on the console after exit❌ happens⚠️ fixed in every fixed order, but with no fixed order the input or the output code page is now and then left at 65001✅ neverlog / log (T2, cmd, bun → bun); PR: log (932, run 19 with the watcher: after exit input 932, output 65001); counts in the table of the timeline
H2The result is decided by the start and exit order, so it changes from run to run❌ happens⚠️ with no fixed order the screen was always correct, but 65001 is now and then left (H3)✅ neverT5, same shape as bun#43660: the four fixed orders in T5 give four different outcomes
H7It happens even when the two Bun processes are not directly connected❌ happens✅ fixed✅ neverscreen / screen (T5 relay, bun | node | bun)

PR #43662 (the open fix for bun#43660)

PR #43662 writes console output with WriteConsoleW through bun_sys::write, and at exit restores a code page only if the saved value is not 65001. Its Windows x64 CI build was run through the same suite. It fixes what bun#43660 reported, but it keeps switching the console to 65001 at startup, so the harms that come from changing shared state remain:

The data flowing through the pipe itself was never corrupted, in any combination (T2). Every harm comes from rewriting shared state: the code page of the console. The stable and canary builds gave the same verdicts in every fixed case (T6), and every fixed verdict was the same at 932 and 437.

Related PRs

Named in robobun's reply on PR #43662. Both were open and not merged on 2026-10-10.

Where in Bun's source

The links point to the current main. The timeline in T5 matches this code exactly: each process saves the value it sees at start, so the second process saves 65001.

T1. Code page over time

A single process runs in the console and prints abc 東京大阪 xyz. Values are input/output.

Test code: T1 (codepage.test.ts lines 35 to 51)

T2. Pipe combinations

The writer and the reader start together, and the reader writes the received bytes to a file. Each cell is "bytes, code page after exit", for a console started at 932 and at 437.

Test code: T2 (codepage.test.ts lines 53 to 81)

The command for each launcher is built here: lines 58 to 61

Writer → readercmdpwsh 7Windows PowerShell 5.1
bun → bun932: ✅ ❌
437: ✅ ❌
932: ✅ ❌
437: ✅ ❌
932: ✅ ✅
437: ✅ ✅
bun → node932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
bun → deno932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
canary → canary932: ✅ ❌
437: ✅ ❌
932: ✅ ❌
437: ✅ ❌
932: ✅ ✅
437: ✅ ✅
canary → node932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
canary → deno932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
pr43662 → pr43662932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
pr43662 → node932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
pr43662 → deno932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
node → bun932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
node → canary932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
node → pr43662932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
node → node932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
node → deno932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
deno → bun932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
deno → canary932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
deno → pr43662932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
deno → node932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
deno → deno932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅
932: ✅ ✅
437: ✅ ✅

T3, T4. Forced kill and neighboring processes

T3. Forced kill

A single process that has written to the screen and is waiting is stopped with taskkill /F.

Test code: T3 (codepage.test.ts lines 83 to 102)

Because Bun restores the code page on exit, a forced kill leaves 65001 behind (H6). A cmd script that runs in the same console afterwards misreads its own source as UTF-8 and is garbled (H4).

T4. After a normal exit

The console after bun | bun exits normally (the lifetimes overlap and the writer exits first).

Test code: T4 (codepage.test.ts lines 104 to 121)

The screen with Bun, at 932 and at 437:

abc 譚ア莠ャ螟ァ髦ェ xyz          abc µ¥▒Σ║¼σñºΘÿ¬ xyz
--- tail ---                  --- tail ---
Active code page: 65001       Active code page: 65001
neighbor: �������             neighbor: caf�

The same with Node.js, at 932 and at 437:

abc 東京大阪 xyz              abc 東京大阪 xyz
--- tail ---                  --- tail ---
現在のコード ページ: 932      Active code page: 437
neighbor: 東京大阪            neighbor: café

現在のコード ページ is the Japanese form of Active code page; on Japanese Windows it switches to English when the output code page is 65001. With both Bun builds, even without a forced kill, the neighbor script and chcp in the same console were affected (H4).

T5. Reproduction with fixed ordering

The second process starts about one second later, and the exit order is decided by delays. The two lifetimes always overlap. Each combination runs three times. Cells are "screen or bytes / starting code page after exit", for a console started at 932 and at 437. The prediction for each order is in T5 of the plan: ww garbled with 65001 left, wr and rw correct, rr correct with 65001 left.

Test code: T5 (codepage.test.ts lines 123 to 210)

Shape and orderbun 1.4.3bun canarybun PR #43662nodedeno
Writer starts first and exits first (ww)
reader writes to the screen
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Writer starts first and exits first (ww)
reader writes to a file
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Writer starts first, reader exits first (wr)
reader writes to the screen
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Writer starts first, reader exits first (wr)
reader writes to a file
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Reader starts first, writer exits first (rw)
reader writes to the screen
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Reader starts first, writer exits first (rw)
reader writes to a file
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Reader starts first and exits first (rr)
reader writes to the screen
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Reader starts first and exits first (rr)
reader writes to a file
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ❌❌❌
437: ✅✅✅ / ❌❌❌
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
Node.js in the middle; writer starts first and exits first (relay)
reader writes to the screen
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
932: ✅✅✅ / ✅✅✅
437: ✅✅✅ / ✅✅✅
ww, reader writes with fs.writeSync(1) (ww-fswritesync)
reader writes to the screen
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ✅✅✅
437: ❌❌❌ / ✅✅✅
932: —
437: —
932: —
437: —
ww, reader writes with fs.write(1) (ww-fswrite)
reader writes to the screen
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ✅✅✅
437: ❌❌❌ / ✅✅✅
932: —
437: —
932: —
437: —
ww, reader writes with Bun.write(Bun.stdout) (ww-bunwrite)
reader writes to the screen
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ❌❌❌
437: ❌❌❌ / ❌❌❌
932: ❌❌❌ / ✅✅✅
437: ❌❌❌ / ✅✅✅
932: —
437: —
932: —
437: —

For Bun 1.4.3 and canary, every combination matched the prediction of the plan, and all three runs were identical, at both 932 and 437. Once the order is fixed, the result is fixed. The build of PR #43662 was correct in every order when the reader writes with process.stdout, but the last three rows, where the reader writes the same text with fs.writeSync(1), fs.write(1) or Bun.write(Bun.stdout), are garbled on every build: those APIs still use WriteFile. These rows run with Bun builds only (Bun.write exists only in Bun).

Timeline of the garbling order (Bun 1.4.3, ww, screen, 932)

From this log. Values are input/output. w is the writer, r the reader, probe the observer Node.js process. The run at 437 gives the same picture with 437 in place of 932 (log).

   0ms probe  before          932/932
  45ms w      after start     65001/65001   ← the writer saves 932 and sets 65001
  47ms w      before writing  65001/65001
1093ms r      after start     65001/65001   ← the reader saves 65001 as the "original" value
2050ms w      before exit     65001/65001   → the writer exits and restores the saved 932
2854ms r      before writing  932/932       ← the reader writes UTF-8 bytes to a 932 console (garbled)
2860ms r      before exit     932/932       → the reader exits and restores the saved 65001
2989ms probe  after           65001/65001   ← 65001 is left behind

T5. Same shape as bun#43660

The same shape as bun#43660: both processes start together, with no fixed order, ten times (60 times for the build of PR #43662). The text is abc 東京大阪 xyz, passed with \u escapes (deno eval for Deno).

bun -e "console.log('abc \u6771\u4eac\u5927\u962a xyz')" | bun -e "process.stdin.pipe(process.stdout)"

Test code: same shape as bun#43660 (codepage.test.ts lines 140 to 161)

RuntimeStart 932: screen / afterStart 437: screen / after
bun 1.4.3❌❌❌❌❌✅✅❌❌❌ / ❌❌❌❌❌✅✅❌❌❌
garbled 8 of 10
❌❌❌❌❌❌❌❌❌✅ / ❌❌❌❌❌❌❌❌❌✅
garbled 9 of 10
bun canary❌❌❌❌❌❌❌❌❌❌ / ❌❌❌❌❌❌❌❌❌❌
garbled 10 of 10
❌❌❌❌❌❌✅❌❌❌ / ❌❌❌❌❌❌✅❌❌❌
garbled 9 of 10
bun PR #43662✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
garbled 0 of 60
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
garbled 0 of 60
node✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅
garbled 0 of 10
✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅
garbled 0 of 10
deno✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅
garbled 0 of 10
✅✅✅✅✅✅✅✅✅✅ / ✅✅✅✅✅✅✅✅✅✅
garbled 0 of 10

Timeline of every process on the console (PR #43662)

To see which processes were on the console when the code page was left changed, the same command was run 60 more times with the build of PR #43662, starting at 932. A Node.js watcher was attached to the same console the whole time. It polled GetConsoleProcessList, GetConsoleCP and GetConsoleOutputCP continuously and logged every attach, every detach and every code page change with a UTC time (watch.ndjson). Node.js does not change the code page (T1).

The same shape was run several times, with and without the watcher. How often the code page was not restored changes a lot from day to day. Every series is listed, including those where it never happened.

Date run (UTC)WatcherRunsNot restoredEvidence
2026-10-07no (full suite)20❌ 1 (932 run 6, output side)log.jsonl (at that commit)
2026-10-10yes60❌ 3 (runs 19, 45, 51)results.jsonl
2026-10-10no (full suite)120✅ 0 (60 each at 932 and 437)932 / 437
2026-10-11yes20❌ 1 (run 9, output side)watch.ndjson, results.jsonl
2026-10-11yes60✅ 0results.jsonl
2026-10-11yes (started at 437)60❌ 2 (runs 48, 55, input)results.jsonl
2026-10-11yes + per-call trace40❌ 3 (runs 6, 15, 21, output)trace below

Starting at 437 left the code page behind in the same way. Both times it was the input side, the same shape as runs 45 and 51 of 2026-10-10.

Run 9 on 2026-10-11 had the same shape as run 19 below: R started 7 ms after W set 65001, and after exit the console was left at input 932, output 65001. What follows analyzes the 60 runs of 2026-10-10.

RunAfter exit (in / out)Processes on the consoleTimeline
19❌ 932 / 65001cmd.exe running the batch file, the Node.js probes before and after, chcp and the two bun processes. No other processwatch.ndjson
45❌ 65001 / 932watch.ndjson
51❌ 65001 / 932watch.ndjson

The other 57 runs returned to 932 / 932 (results.jsonl, environment.json). The three runs, the bun lines only (UTC). W is the writer bun -e "console.log(...)" and R is the reader bun -e "process.stdin.pipe(process.stdout)":

run 19
13:39:12.205  attach  W
13:39:12.208  codepage in 932   / out 65001
13:39:12.209  codepage in 65001 / out 65001
13:39:12.216  attach  R
13:39:12.223  codepage in 932   / out 65001
13:39:12.226  detach  W
13:39:12.226  codepage in 65001 / out 65001
13:39:12.263  codepage in 932   / out 65001
13:39:12.266  detach  R
              (left at in 932 / out 65001)

run 45
13:39:50.176  attach  W
13:39:50.179  codepage in 932   / out 65001
13:39:50.181  codepage in 65001 / out 65001
13:39:50.189  attach  R
13:39:50.192  codepage in 65001 / out 932
13:39:50.194  detach  W
13:39:50.227  detach  R
              (left at in 65001 / out 932)

run 51
13:39:58.957  attach  W
13:39:58.959  codepage in 932   / out 65001
13:39:58.960  codepage in 65001 / out 65001
13:39:58.970  attach  R
13:39:58.974  codepage in 65001 / out 932
13:39:58.975  detach  W
13:39:59.011  detach  R
              (left at in 65001 / out 932)

The order, derived from the PR's source

The tested build is the PR's head commit 576eb251a. Its output.rs is the only place that changes the code page:

With only W and R calling these, each final state has a single order that produces it:

Up to here this is a deduction from the source and the timestamps: the watcher does not see which process made each call, and the step between R's save and R's set is shorter than its sampling interval (in run 19 the output going to 932 and back is not in the log). So the next step recorded each call.

Per-call trace

W and R each ran under cdb (WinDbg 1.2610), with breakpoints on GetConsoleOutputCP, SetConsoleOutputCP, GetConsoleCP and SetConsoleCP in kernelbase. Each hit recorded the process, the value (the argument of Set, the return value of Get) and the caller address, then continued (trace-writer.ndjson, trace-reader.ndjson). The watcher ran as well. Of 40 runs from 932, 3 left the output code page at 65001.

Run 6 (UTC). W is pid 30744, R is pid 55480:

21:30:27.486  W  GetConsoleOutputCP -> 932     (saves 932)
21:30:27.500  W  SetConsoleOutputCP(65001)
21:30:27.509  W  GetConsoleCP       -> 932
21:30:27.511  W  SetConsoleCP(65001)
21:30:27.514  R  GetConsoleOutputCP -> 65001   (saves 65001)
21:30:27.525  W  SetConsoleOutputCP(932)       (W restores output)
21:30:27.527  W  SetConsoleCP(932)             (W restores input)
21:30:27.528  R  SetConsoleOutputCP(65001)
21:30:27.537  R  GetConsoleCP       -> 932
21:30:27.539  R  SetConsoleCP(65001)
21:30:27.594  R  SetConsoleCP(932)             (R restores input only)
              (left at in 932 / out 65001)

The debugger stops bun at every call, so the rate of lost races cannot be compared with runs without it. Each of the two debuggers records its own times, so the order between the two processes can be off by a few ms (in run 21, going by the recorded times alone, R saved after W's restore). The values (what each process saved) are not affected by this. The debugger prints its banner before the script hides its output, so W's banner goes into the pipe and R prints it on the screen (screen.json).

Evidence (run 6): trace-writer.ndjson, trace-reader.ndjson, watch.ndjson. All 40 runs: results.jsonl. Code: tools/50_run/asis-timeline.ts --trace, tools/50_run/cdb-trace.js, summary by tools/50_run/summarize-trace.ts

Code: the watcher (watch.ts) and the runner (asis-timeline.ts)

Conditions

ItemValue
OSWindows 11 Home 10.0.26300 (Japanese)
ConsoleA new console is created with conhost.exe for every case. Its starting code page is set to 932 or 437 with chcp inside that dedicated console, which nothing else shares. The tests never change the code page after that
Bun1.4.3+c6da4a4d3
Bun canary1.4.3-canary.1+bbdc5a519 (the latest at setup time)
Bun PR #436621.4.3-canary.1+6b5271cb1: the Windows x64 CI build of PR #43662, the open fix for bun#43660 (head commit 6b5271cb1, Buildkite build 126042). Earlier results were measured on 576eb251a (Buildkite build 119166). The timeline of every process in the console and the cdb records after it remain those of 576eb251a
Node.jsv26.10.0
Deno2.9.7
pwsh / Windows PowerShell7.6.6 / 5.1.26100.9549
Text sentabc 東京大阪 xyz ("Tokyo Osaka"). Garbled it becomes abc 譚ア莠ャ螟ァ髦ェ xyz at 932 and abc µ¥▒Σ║¼σñºΘÿ¬ xyz at 437
How to runtools\10_setup\setup-runtimes.cmd downloads the runtimes above from their official sources into _bin\, and tools\40_test\run-tests.cmd puts them first on PATH and runs everything. Nothing installed on the PC is used

How results are judged

✅ as expected (same as the expected behavior) / ❌ not as expected. Every ✅ and ❌ in the tables below is a link to the evidence file of that case: the screen (screen.json), the log with the code pages (log.jsonl) or the received bytes (out.bin).

Evidence

All files are in research/evidence/, one folder per case: cp<code page>/<bun or bun-canary>/<runner>/<case>/. Each case folder holds the batch file it ran (run.cmd), the log, the screen and, if any, the received bytes. The logs hold no date and no pid, so two runs can be compared with diff. The run time and the tool versions are only in the environment.json of each pass:

Test code

All links point to commit 5b9f56b, so the line numbers do not move.