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
{{ message }}
Repository navigation
Patch returns stale diff and writes lose BOM after partial formatter failure #61415
When a formatter writes corrections and then exits nonzero, Patch reports the pre-format diff even though the file on disk contains the corrections. A formatter that rewrites a UTF-8 BOM file without the BOM also leaves it missing after Patch or Write.
Formatter.file() returns false when no formatter succeeds. Both callers treat that as evidence that the file was unchanged: Patch uses its pre-format text, and FileWrite skips BOM synchronization. A nonzero exit code does not guarantee absence of writes.
Reproduction
On dev at 6d1c444, configure a formatter for .txt that runs:
Start with a UTF-8 BOM file containing before\n, then use Patch to replace before with created. The resulting file contains FORMATTED\n without its BOM, while output.files and metadata.files report +created. Write also loses the BOM with the same formatter.
Expected: Patch's diff reflects the final disk contents, and the original BOM is restored even if formatting exits unsuccessfully. This is a valid formatter outcome: RuboCop --autocorrect, for example, can correct some offenses while exiting 1 for remaining offenses.
Reproduced with the real Formatter service and a real Bun subprocess on Windows (Bun 1.4.4). Both regression tests fail on the current base.
Thanks for the detailed report. I reproduced this on dev at 6d1c444, which is also the latest dev.
A real .txt formatter that writes FORMATTED\n and then exits 1 changes the file, but Formatter.file() returns false.
Patch: on a UTF-8 BOM file containing before\n, replacing before with created reports -before / +created. The file on disk ends up as FORMATTED\n with no BOM.
Write: with the same formatter, the BOM is lost too.
In both tools, false is taken to mean the file wasn't touched. Patch then reports its pre-format text and skips restoring the BOM, and Write returns before restoring it. The script below adds the regression tests to a checkout and runs them; the Patch and Write tests fail on current dev.
Closely related, but not duplicates: #35071 and #23797 (keeping the BOM in file tools), #31422 (auto-formatting vs. apply_patch).
Activity
opencodejr commentedon Nov 3, 2026
Thanks for the detailed report. I reproduced this on
devat 6d1c444, which is also the latestdev..txtformatter that writesFORMATTED\nand then exits 1 changes the file, butFormatter.file()returnsfalse.before\n, replacingbeforewithcreatedreports-before / +created. The file on disk ends up asFORMATTED\nwith no BOM.In both tools,
falseis taken to mean the file wasn't touched. Patch then reports its pre-format text and skips restoring the BOM, and Write returns before restoring it. The script below adds the regression tests to a checkout and runs them; the Patch and Write tests fail on currentdev.Closely related, but not duplicates: #35071 and #23797 (keeping the BOM in file tools), #31422 (auto-formatting vs.
apply_patch).Reproduction script (repro.sh)
Run it:
bash repro.sh