document.currentScript does not exist in Starling. Google's https://accounts.google.com/gsi/client ends with a style-injection IIFE that reads document.currentScript.nonce. The read throws TypeError: Cannot read properties of undefined (reading 'nonce'), the Starling DOM fires the script element's error event instead of load, and x.com treats Google Identity Services as failed — Google sign-in never initializes. Logged as uncaught dynamic script error (https://accounts.google.com/gsi/client).
What happens
- A repo-wide grep for
currentScript in src/ has zero hits. The document prototype accessor block (src/Starling.Bindings/NodeBindings.cs, starting around line 1487 — readyState, body, head, activeElement, and so on) defines no currentScript.
- The dynamic classic-script path
StarlingDynamicScriptRunner.RunOneAsync (src/Starling.Bindings/Backend/StarlingDynamicScriptRunner.cs:93-157, the run at line 139) holds the script element in scope but never sets a current-script slot around the run.
- The parser-batch path cannot do it today even if it wanted to:
IScriptSession.RunClassicScript(string source, string label) (src/Starling.Js.Hosting/IScriptSession.cs:95, implemented at src/Starling.Bindings/Backend/StarlingScriptSession.cs:126-178, called from src/Starling.Engine/Engine.cs:1477) does not receive the script element. A seam change is needed.
- Reading the missing property yields
undefined, and the .nonce member read throws via src/Starling.Js/Runtime/JsVm.cs:1133. The dynamic runner contains the failure (StarlingDynamicScriptRunner.cs:143-148, log template at line 191) and fires error instead of load on the element.
- Also missing: the
nonce IDL (interface definition language) attribute on elements. Chromium exposes it on HTMLElement.prototype and returns "" by default.
Chromium ground truth (verified 2026-06-10 via Playwright): during a dynamically inserted classic script's execution, document.currentScript is the script element, element.nonce is "", and currentScript reverts to null afterwards. Module scripts always see null.
Repro
Verified 2026-06-10 on the real engine via a scratch harness (console app referencing Starling.Bindings, driving CreateSession + RunClassicScript + a pump). A page script injects <script src=...>. The probe script observes typeof document.currentScript === "undefined", then document.currentScript.nonce throws the exact observed TypeError, and error fires instead of load. The parser-batch path also reports undefined.
Fix
Real fix: implement the HTML "execute the script block" current-script steps:
- a per-document slot (not per-realm — iframes share the realm bootstrap, but each document needs its own slot)
- set to the element before running a classic script, restored after (and
null for module scripts)
- applied on both paths: the dynamic runner (the element is already in scope) and the parser batch (pass the element through the
RunClassicScript seam, or have the engine set the Starling DOM slot before the call)
- add the
HTMLElement.nonce IDL attribute (default "", reflects the content attribute) for parity — other loaders that are aware of Content Security Policy read it the same way
There is no cheap stub. Defining document.currentScript as a constant null does not fix gsi/client: null.nonce throws the same TypeError, just with a different message. Only the real slot, set during execution, makes the guard evaluate to the falsy "" and lets the script finish.
Context
Found during the x.com/nasa boot investigation on 2026-06-10 (branch feat/js-stack-trampoline). The crash is the file's last statement, so the GSI library body has already executed when it dies — but the error event makes loaders treat the whole script as failed.
document.currentScriptdoes not exist in Starling. Google'shttps://accounts.google.com/gsi/clientends with a style-injection IIFE that readsdocument.currentScript.nonce. The read throwsTypeError: Cannot read properties of undefined (reading 'nonce'), the Starling DOM fires the script element'serrorevent instead ofload, and x.com treats Google Identity Services as failed — Google sign-in never initializes. Logged asuncaught dynamic script error (https://accounts.google.com/gsi/client).What happens
currentScriptinsrc/has zero hits. The document prototype accessor block (src/Starling.Bindings/NodeBindings.cs, starting around line 1487 —readyState,body,head,activeElement, and so on) defines nocurrentScript.StarlingDynamicScriptRunner.RunOneAsync(src/Starling.Bindings/Backend/StarlingDynamicScriptRunner.cs:93-157, the run at line 139) holds the script element in scope but never sets a current-script slot around the run.IScriptSession.RunClassicScript(string source, string label)(src/Starling.Js.Hosting/IScriptSession.cs:95, implemented atsrc/Starling.Bindings/Backend/StarlingScriptSession.cs:126-178, called fromsrc/Starling.Engine/Engine.cs:1477) does not receive the script element. A seam change is needed.undefined, and the.noncemember read throws viasrc/Starling.Js/Runtime/JsVm.cs:1133. The dynamic runner contains the failure (StarlingDynamicScriptRunner.cs:143-148, log template at line 191) and fireserrorinstead ofloadon the element.nonceIDL (interface definition language) attribute on elements. Chromium exposes it onHTMLElement.prototypeand returns""by default.Chromium ground truth (verified 2026-06-10 via Playwright): during a dynamically inserted classic script's execution,
document.currentScriptis the script element,element.nonceis"", andcurrentScriptreverts tonullafterwards. Module scripts always seenull.Repro
Verified 2026-06-10 on the real engine via a scratch harness (console app referencing
Starling.Bindings, drivingCreateSession+RunClassicScript+ a pump). A page script injects<script src=...>. The probe script observestypeof document.currentScript === "undefined", thendocument.currentScript.noncethrows the exact observed TypeError, anderrorfires instead ofload. The parser-batch path also reportsundefined.Fix
Real fix: implement the HTML "execute the script block" current-script steps:
nullfor module scripts)RunClassicScriptseam, or have the engine set the Starling DOM slot before the call)HTMLElement.nonceIDL attribute (default"", reflects the content attribute) for parity — other loaders that are aware of Content Security Policy read it the same wayThere is no cheap stub. Defining
document.currentScriptas a constantnulldoes not fix gsi/client:null.noncethrows the same TypeError, just with a different message. Only the real slot, set during execution, makes the guard evaluate to the falsy""and lets the script finish.Context
Found during the x.com/nasa boot investigation on 2026-06-10 (branch
feat/js-stack-trampoline). The crash is the file's last statement, so the GSI library body has already executed when it dies — but theerrorevent makes loaders treat the whole script as failed.