Skip to content

feat: add --fallback-to-source flag for bytecode failures#246

Merged
robertsLando merged 3 commits intomainfrom
feat/fallback-to-source
Apr 17, 2026
Merged

feat: add --fallback-to-source flag for bytecode failures#246
robertsLando merged 3 commits intomainfrom
feat/fallback-to-source

Conversation

@robertsLando
Copy link
Copy Markdown
Member

Summary

Test plan

  • Cross-compile without --fallback-to-source → verify warning is logged with flag hint and file is skipped (no UNEXPECTED-20 crash)
  • Cross-compile with --fallback-to-source → verify warning is logged and file is shipped as plain source
  • Native compile (no fabrication failure) → verify no change in behaviour with or without the flag
  • pkg --help shows the new flag

🤖 Generated with Claude Code

robertsLando and others added 2 commits April 16, 2026 15:08
The automatic fallback to source introduced in 46a7f8e shipped plain
source whenever V8 bytecode fabrication failed, without the user
explicitly opting in. This moves that behaviour behind a new
--fallback-to-source flag.

Default (no flag): warn about the failure, mention --fallback-to-source
in the warning, and skip the file. The empty VFS key is cleaned up so
the prelude no longer hits "Error: UNEXPECTED-20" (#87, #181).

With --fallback-to-source: ship the file as plain source (previous
automatic behaviour).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Default (no --fallback-to-source): warn, mark the stripe as skipped,
and emit a zero-byte buffer — identical to the pre-46a7f8e behaviour.
If the file is required at runtime the prelude now throws a descriptive
UNEXPECTED-20 error naming the file and suggesting --fallback-to-source,
--no-bytecode, or --sea.

test-50-extensions needs source at runtime during cross-compile so it
now passes --fallback-to-source explicitly.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The walker emits both STORE_BLOB and STORE_CONTENT stripes for public
files (lib/walker.ts:987-1003), so when bytecode fabrication fails the
source is still available at runtime. No --fallback-to-source needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@robertsLando robertsLando merged commit 5eb4681 into main Apr 17, 2026
27 checks passed
@robertsLando robertsLando deleted the feat/fallback-to-source branch April 17, 2026 06:25
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new --fallback-to-source CLI flag to control what happens when V8 bytecode generation fails during packaging (commonly in cross-compilation scenarios). The intent is to make the default behavior “warn and skip the file” (instead of silently falling back to shipping source), while preserving the prior fallback behavior when the flag is explicitly enabled.

Changes:

  • Add --fallback-to-source to CLI parsing and help output, and plumb the option into the producer pipeline.
  • Change bytecode fabrication failure handling to either (a) ship plaintext source (flag enabled) or (b) warn and skip the file (default).
  • Update docs to describe the new flag and recommended mitigations; update an existing test to pass the new flag.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
lib/index.ts Adds the new boolean CLI flag and passes it into producer() options.
lib/producer.ts Implements flag-driven behavior on bytecode fabrication failures; introduces Stripe.skip.
lib/packer.ts Extends Stripe type with optional skip metadata.
prelude/bootstrap.js Improves the runtime error message when a VFS entry has neither source nor bytecode.
lib/help.ts Documents the new flag in pkg --help output.
test/test-50-extensions/main.js Updates an existing integration test invocation to include --fallback-to-source.
docs-site/guide/targets.md Adds “fallback to source” as an option in cross-compilation guidance.
docs-site/guide/getting-started.md Adds the flag to the CLI reference table.
docs-site/guide/bytecode.md Adds a new section documenting fallback-to-source behavior.
Comments suppressed due to low confidence (1)

lib/producer.ts:455

  • The new skip mechanism only prevents recording the previous stripe’s payload range, but the VFS key is still pre-created earlier and other stripes for the same snap (notably STORE_STAT) will still be recorded. This leaves a VFS entry that existsSync/statSync considers present, but readFileSync later fails with UNEXPECTED-20. To truly “skip the file”, ensure no VFS entry (and no STORE_STAT) is emitted for that snap—e.g., build VFS entries lazily when adding a store, and/or track skipped snaps and suppress all subsequent stripes for them (and delete any pre-created VFS key).
      if (count === 2) {
        if (prevStripe && !prevStripe.skip) {
          const { store } = prevStripe;
          let { snap } = prevStripe;
          snap = snapshotify(snap, slash);
          const vfsKey = makeKey(doCompress, snap, slash);
          vfs[vfsKey][store] = [track, meter.bytes];
          track += meter.bytes;
        }

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