Repository navigation
Conversation
JavaScriptCore rejects a program when any link of the global object's prototype chain is a Proxy. Every Bun global clears IsImmutablePrototypeExoticObject from its structure, so user code can set that prototype, and jsdom 28+ puts a Proxy in the chain of its window. Opt every Bun global out of the check, as V8 permits it. This needs oven-sh/WebKit#626.
|
Warning Review limit reached
On-demand reviews are free for the next 9 days. After that, they cost $0.25 per reviewed file. Or wait 8 minutes for your next included review. View limit detailsLimit details: You’ve used all 10 included reviews currently available. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (3)
Comment |
|
Updated 11:07 AM PT - Sep 11th, 2026
✅ @robobun, your commit 776a00d5645519a5b843f075a881f5a2f9dec7b0 passed in 🧪 To try this PR locally: bunx bun-pr 42347That installs a local version of the PR into your bun-42347 --bun |
| * From https://github.com/oven-sh/WebKit releases. | ||
| */ | ||
| export const WEBKIT_VERSION = "cf1b36ec8703d8e87436094d21d478d358c7d886"; | ||
| export const WEBKIT_VERSION = "autobuild-preview-pr-626-f1e23f97"; |
There was a problem hiding this comment.
🔴 WEBKIT_VERSION is pinned to autobuild-preview-pr-626-f1e23f97, an ephemeral preview-PR build tag; merging this makes every fresh checkout and CI lane depend on an artifact that disappears once oven-sh/WebKit#626 closes, breaking the build for everyone (base pins a merged SHA). Fix: before merge, repin to the merged upstream SHA and verify prebuilt WebKit artifacts exist for every platform × flavor, per scripts/build/deps/README.md and the Dependencies & vendoring rule. The PR body notes this as a repin step, but the pin as committed is still the merge-blocker.
Extended reasoning...
scripts/build/deps/webkit.ts:6 sets WEBKIT_VERSION = "autobuild-preview-pr-626-f1e23f97". WebKit is a prebuilt dep — resolveDep downloads a release artifact keyed on this string from oven-sh/WebKit. Preview-PR autobuild tags are deleted when the PR is merged or closed, so after that point dep_fetch 404s and bun bd / CI fails at the WebKit fetch step on any machine without a cached copy. The base branch pins a real merged SHA (cf1b36ec…) whose artifacts are permanent. The repo's dependency-pin convention explicitly forbids merging a pin to an ephemeral artifact; the author's own PR body says "Repin it to the merged sha before this merges", confirming the tag is temporary.
Verification: normal — acknowledged in diff: the PR body states "WEBKIT_VERSION points at the preview build of oven-sh/WebKit#626. Repin it to the merged sha before this merges", which is accurate but does not resolve the hazard; the code as it stands is not mergeable. scripts/build/deps/webkit.ts:6 changes the pin from a permanent merged SHA to an ephemeral preview-PR tag: ``` -export const…
There was a problem hiding this comment.
Agreed. The preview tag is only there so CI can build against oven-sh/WebKit#626 before it merges. I will repin WEBKIT_VERSION to the merged sha as soon as that PR lands, and this PR stays a draft for merging until then. Leaving this thread open as the reminder.
Opt Bun globals into the pinned OpenClaw WebKit capability for Proxy prototype chains, restoring jsdom Window program execution. Cover contextified globals, declarations, inherited lookup and the main realm. Ports oven-sh#42347. Requires OpenClaw WebKit. Linux regression and OpenClaw theme proof pass; both fork native CI lanes pass on the guarded PR head. Co-authored-by: robobun <117481402+robobun@users.noreply.github.com>
|
Superseded by #44833. |
|
Confirmed. #44833 pins a WebKit that skips the Proxy check for every Bun global (ProgramExecutable.cpp, oven-sh/WebKit#781), so this change is no longer needed. The issue repro prints 2 on 1.4.4-canary.1. |
Problem
vm.runInContext(code, ctx)throwsTypeError: Proxy is not allowed in the global prototype chain.when the context global has a Proxy anywhere in its prototype chain. jsdom 28+ puts one there (WindowProperties), so jsdom undernode:vmand Vitestpool: 'vmThreads'fail on Bun. Node prints the result. Fixes node:vm rejects a Proxy in a DONT_CONTEXTIFY global prototype chain, breaking jsdom with Vitest vmThreads #42331.Object.setPrototypeOf(globalThis, Object.create(new Proxy({}, {}))),vm.runInThisContext()and CommonJSrequire()throw the same error.ProgramExecutable::initializeGlobalProperties. It runs before every program links. Bun has no hook to skip it, so the fix needs [JSC] Let an embedder allow a Proxy in the prototype chain of its global object WebKit#626.Fix
JSGlobalObject::setAllowsProxyInPrototypeChain(). A global object that opts in skips the check.Bun::GlobalScope::finishCreation(src/jsc/bindings/BunGlobalScope.cpp) opts in, so every Bun global is covered: main, workers, shadow realms andnode:vmcontexts.IsImmutablePrototypeExoticObjectfrom its structure (ZigGlobalObject.cpp:443,NodeVM.cpp:941), so user code can set its prototype. Global declaration instantiation in JSC reads only own properties of the global, so no Proxy trap runs while a program links. Name lookup at run time goes through the ordinary[[HasProperty]],[[Get]]and[[Set]]paths, which handle a Proxy. That matches V8.WEBKIT_VERSIONpoints at the preview build of [JSC] Let an embedder allow a Proxy in the prototype chain of its global object WebKit#626. Repin it to the merged sha before this merges.test/js/node/vm/vm.test.ts, block "a Proxy in the prototype chain of the context global" (4 tests, all fail on Bun 1.4.2). Also the rest oftest/js/node/vm, the 95 vendoredtest/js/node/test/parallel/test-vm-*.js, and jsdom 30 undervm.runInContext.Background
ProgramExecutableis whatvm.runInContext,vm.runInThisContext,new vm.Script().runIn*and the CommonJS loader evaluate. Modules andevaldo not go through it, so they never hit the check.[[SetPrototypeOf]]refuses a new value. The spec makesObject.prototypeone, and JSC makes global objects one by default. Bun clears that flag on its globals so jsdom can set__proto__on the window.Window.prototypeis mutable andvardeclaration walked the prototype chain at the time. JSC's declaration code is own-property only today.Notes
Node behaviour the tests follow: in a
DONT_CONTEXTIFYcontext a missing name throwsReferenceError. In a contextified context it reads asundefined(the sandbox interceptor). Node'shas/get/settraps fire on a Proxy in the chain for unresolved names and sloppy assignments, and the Proxy target is never written (the receiver is the global). Bun now produces the same results.Pre-existing, unrelated:
varand function declarations in aDONT_CONTEXTIFYcontext do not create bindings in Bun, with or without a Proxy in the chain. The declaration test therefore uses a contextified context.test/js/node/vm/script-leak.test.tstimes out at 5 s in the container used here, on main as well as on this branch (16 s of parse time for 10000 scripts in a debug ASAN build).Self-reviewed: the review found that the first version opted in only the
node:vmglobal and missed the main realm, and that the PR body claimed the main global could not get a Proxy in its chain. Both fixed: the opt-in moved toBun::GlobalScope, and a main realm test was added. The review also asked for the preview pin to be replaced by the merged sha, which is the repin step above.no test proof · iteration 0 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/js/node/vm/vm.test.ts