Repository navigation
On Bun ≥ 1.3.5, hosted and vendored rewiring drops Bun's default trust, so install scripts of patched packages (better-sqlite3, esbuild, sharp…) are silently blocked #371
Description
[agent] Found by the scheduled Bun bug-hunt routine (ledger #306).
Summary
Bun runs dependency lifecycle scripts only for packages in trustedDependencies, plus Bun's built-in default-trusted list (better-sqlite3, esbuild, sharp, bcrypt, @prisma/client, electron, cypress, …). From Bun 1.3.5 on, the default list only applies to packages resolved from the npm registry. When socket-patch rewires one of these packages to a hosted URL tuple (scan --mode hosted) or a .socket/vendor/... local tarball (scan --mode vendored), Bun no longer trusts it. The package's install / postinstall script is skipped, and bun pm untrusted now lists it.
socket-patch reports success with no warning, and bun install --frozen-lockfile exits 0. But the installed package is broken at runtime whenever it needs its install script: native bindings aren't built or downloaded, binaries aren't fetched, and so on.
Impact
better-sqlite3@11.10.0: after rewiring,require('better-sqlite3')throwsCould not locate the bindings file. The control (same lock, unrewired, fresh frozen install) loads fine.- Any default-trusted package whose install script does real work breaks the same way. Nothing in the envelope, the lock or the frozen install's exit code signals it. It shows up only as a runtime crash, typically in CI or production after a fresh install.
Repro (Linux, main f6b7fb9, bun 1.4.2)
mkdir tr && cd tr
printf '{"name":"app","version":"1.0.0","dependencies":{"better-sqlite3":"11.10.0"}}\n' > package.json
bun install
node -e 'require("better-sqlite3")(":memory:");console.log("LOADS")' # LOADS
socket-patch scan --mode hosted --json --yes --api-url <mock> --org test-org --api-token fake # or --mode vendored
# status "success", redirect.warnings []
mkdir ../fresh && cp -a package.json bun.lock .socket ../fresh/ && cd ../fresh
bun install --frozen-lockfile; echo $? # 0
node -e 'require("better-sqlite3")(":memory:")' # Error: Could not locate the bindings file
bun pm untrusted
# ./node_modules/better-sqlite3 @http://…/better-sqlite3-11.10.0.tgz
# » [install]: prebuild-install || node-gyp rebuild --releaseThe mock serves a patched copy of the real registry tarball: the same files, with a marker prepended to lib/index.js, and the same scripts.
Workaround, which I verified: adding "trustedDependencies": ["better-sqlite3"] to package.json makes the fresh frozen install run the script again, and the module loads.
Expected vs actual
- Expected: rewiring changes the bytes of the patched package and nothing else. The docs (docs/testing/bun-compatibility.md, "Formats and rewrite behavior") describe the rewrite as keeping the meta object verbatim so the install behaves the same. A package that was trusted before the rewrite should stay trusted, for example by adding it to
trustedDependencies(and rollback removing it). At minimum the run should warn that the package's lifecycle scripts will now be blocked. - Actual: trust is silently lost and the install scripts don't run.
OS × version (hosted and vendored behave identically)
| OS | Bun 1.1.45 | Bun 1.2.23 | Bun 1.3.0 / 1.3.2 / 1.3.4 | Bun 1.3.5 | Bun 1.3.6 / 1.3.9 / 1.3.14 | Bun 1.4.2 |
|---|---|---|---|---|---|---|
| Linux (sandbox) | pass | pass | pass | fail | fail | fail |
| ubuntu-latest | — | — | pass (1.3.4) | fail | — | fail |
| macos-latest | — | — | pass (1.3.4) | fail | — | fail |
| windows-latest | — | — | pass (1.3.4) | fail | — | fail |
First bad Bun release: 1.3.5 (1.3.4 passes, bisected on Linux and confirmed on all three runner OSes). This is an upstream Bun behaviour change that socket-patch doesn't compensate for. socket-patch release 4.0.0 behaves the same as main.
Suspect code
- The hosted text and binary rewriters,
crates/socket-patch-core/src/patch/redirect/mod.rs:4329(rewrite_bun_lock) andpatch/redirect/bun_binary.rs:19, plus the vendored bun backend (crates/socket-patch-core/src/vendor/bun_lock.rs). None of them looks at the package'sscriptsor at Bun's default-trust status, or touchestrustedDependencies. - The real-Bun matrix (
scripts/backtest-bun.py) uses--ignore-scriptsfor every measurement (docs/testing/bun-compatibility.md, "Installer boundaries"), so it can't observe this.
Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36766578001 (3 OS × bun 1.3.4 / 1.3.5 / 1.4.2, main built on each runner).
Activity
bun: run 1 ledger (#366 #367 #371)
mikolalysenko commentedon Sep 30, 2026
[agent] Triaged:
priority:p1(Bun, npm family). Not a duplicate, and I found no existing fix PR.The Bun rewriters (
rewrite_bun_lock,rewrite_bun_binaryand the vendoredbun_lockbackend) move a package off a registry resolution without keeping Bun's default trust (trustedDependencies). #367 is related: it's the same rewrite boundary, but a different Bun feature (patchedDependencies) that needs a different fix. So I'm tracking the two separately rather than as one cluster.Generated by Claude Code
mikolalysenko commentedon Oct 7, 2026
Claim-ID: agent/fix-bun-open-issues. Draft fix PR: #1009 (it covers all open
pm:bunissues).Warn when a Bun rewire drops default trust (#371)
Keep the Bun trust warning out of the unredirected hint count (#371)
Reconcile #371 with #578's bun.lock hot-loop budget
Trim per-entry work in the Bun scan paths
Merge origin/main into agent/fix-bun-open-issues