Skip to content

fix: add missing dry_run/no_reapply attrs in cmd_upgrade's self-updat… - #24

Merged
NetVar1337 merged 7 commits into
NetVar1337:mainfrom
citizensarrest:claude/gifted-franklin-ppJrn
Jun 8, 2026
Merged

fix: add missing dry_run/no_reapply attrs in cmd_upgrade's self-updat…#24
NetVar1337 merged 7 commits into
NetVar1337:mainfrom
citizensarrest:claude/gifted-franklin-ppJrn

Conversation

@citizensarrest

Copy link
Copy Markdown
Contributor

…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

claude added 7 commits May 26, 2026 17:32
…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
@NetVar1337
NetVar1337 merged commit 30472b4 into NetVar1337:main Jun 8, 2026
15 checks passed
@citizensarrest
citizensarrest deleted the claude/gifted-franklin-ppJrn branch June 15, 2026 04:13
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.

3 participants