fix: add missing dry_run/no_reapply attrs in cmd_upgrade's self-updat… - #24
Merged
NetVar1337 merged 7 commits intoJun 8, 2026
Merged
Conversation
…e stub
cmd_self_update() reads args.dry_run (line 1155) and args.no_reapply
(line 1163), but cmd_upgrade built the throwaway args object with only
{"force": False}, causing AttributeError on every run.
Fix: include dry_run=False and no_reapply=False in the anonymous type.
https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
…erify failure When patch_bun_sea_inplace applies all patches and the post-patch --version verify fails, the root cause is almost always a patch whose replacement is far shorter than its regex match. The size difference is filled with space bytes, but those spaces overwrite adjacent JS that the greedy regex captured but the replacement never reproduced — e.g. the js-experimental-betas-always-on regex ends with "}func", consuming the first four bytes of the *next* function keyword, leaving "tion nextFunc()" (invalid JS) after padding. Fix: extract the apply+verify logic into an inner _attempt() helper that works on a fresh bytearray copy of the original binary bytes each call. If the first attempt fails with "verify failed" and any patch needed >64 bytes of padding, rebuild without those patches and retry. On success the result carries "skipped_heavy" (sorted list of dropped patch IDs) so cmd_patch can print them as yellow "skip" lines and count them in the skip counter rather than the fail counter. If the retry also fails the original error is returned unchanged, so existing hint/rollback messaging is unaffected. https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
…available _find_active_bundle_bounds previously fell back to the full Bun section range (bun_lo, bun_hi) whenever the u32 size field could not be read — specifically when the '// @Bun @bytecode' marker sits at offset 0 of the .bun section with no preceding bytes for the size field. Bun 2.1.150 (Windows PE) appears to emit the marker at the very start of the .bun section, triggering the fallback unconditionally. With the full range active, every JS patch that matches text in the active bundle ALSO matches the identical text in the VFS copy that follows the bytecode blob, and overwrites it. Bun re-parses the VFS copy at module-load time, so corrupted VFS bytes cause: TypeError: Expected CommonJS module to have a function wrapper regardless of whether any individual patch uses heavy padding. This is why the auto-retry (dropping the 5 heavy-padding patches) also failed — the root cause was not the padding amount but the wrong search bounds. Fix: when size_field_off < section_start OR blob_size is implausible, search for a SECOND occurrence of '// @Bun @bytecode'. That second marker is the header of the VFS copy. Restrict patches to the half-open interval [first_marker, second_marker), which covers the active JS bundle and the binary bytecode-for-deps blob but never reaches the VFS copy. Binary bytecode is dense data that JS text regexes will not accidentally match, making this safe. Falls back to full range only when the section contains a single marker (old single-bundle builds with no VFS). Also surface the retry error when both attempts fail so users can see that the retry ran and what its specific failure was. https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
…uption Root cause (confirmed by vpcc scan offsets): The .bun section in Bun 2.1.150 Windows PE contains the active JS bundle followed by ~102 MB of binary bytecode, then a second copy of the same JS source inside the virtual-filesystem (VFS). When _find_active_bundle_bounds falls back to the full section range, pat.finditer() and data.find() in a while-loop match the same JS pattern in BOTH the active bundle AND the VFS copy, overwriting both. Bun re-parses the VFS copy at module-load time. Corrupted VFS bytes cause: TypeError: Expected CommonJS module to have a function wrapper The fix is simple and layout-independent: switch from finditer()/while-loop to a single search()/find() so only the FIRST occurrence is patched. The active bundle always precedes the VFS copy in the .bun section layout: [active-bundle (JS source)][bytecode-for-deps][VFS copy of same source][trailer] Therefore the first match is always in the active bundle and the VFS copy is never touched, regardless of whether _find_active_bundle_bounds returns correct or fallback bounds. Also bump version to 2.2.2 to bust pip's git-clone cache so 'pipx install --force' always fetches the updated code. https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
…failure
Three changes for diagnosing the persistent verify failure:
1. Extend verify error capture from 120 → 500 chars.
The truncated message cuts off the Bun 'Filename: ...' line that
identifies which module is corrupted. The full text will tell us
exactly where the damage is.
2. Add retry-2: drop ALL patches with any padding (max_padding > 0),
not just the >64 B heavy ones. Patches with moderate padding (1-64 B)
can still corrupt the active bundle when a greedy regex consumed bytes
the replacement did not reproduce. If retry-2 passes, the zero-padding
patch subset is a viable partial fix.
3. Print bounds diagnostic on failure:
diag bun=[0xABCD,0xEFGH) eff=[0xIJKL,0xMNOP) section=NNN eff=NNN
This confirms whether _find_active_bundle_bounds correctly narrowed the
search window (eff << section) or fell back to the full range (eff == section).
Bump version to 2.2.3 to bust pip cache.
https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
_find_active_bundle_bounds rewritten to detect Layout B where the // @Bun @bytecode marker appears far (>4096 bytes) from section start. In that layout the raw JS source lives BEFORE the marker; patch window is [bun_lo, abs_marker) instead of the compiled bytecode region that was being targeted before. Also fixes cmd_upgrade dry_run/no_reapply AttributeError and first-match-only patch application. https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
…ws fix Merges VoidChecksum/void-patcher-cc@upstream/main (v2.4.0: interactive TUI, autopilot/dashboard/guard, retired patch support, v2.1.152 RE) with our Windows PE Layout B patching fix. Conflict resolution: - Keep _attempt() retry structure and first-match-only patching (Layout B fix) - Take upstream's os.replace() atomic swap and Windows chmod try/except https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…e stub
cmd_self_update() reads args.dry_run (line 1155) and args.no_reapply (line 1163), but cmd_upgrade built the throwaway args object with only {"force": False}, causing AttributeError on every run.
Fix: include dry_run=False and no_reapply=False in the anonymous type.
https://claude.ai/code/session_0197AabEVQEHn9ocogcT3Up7