fix(desktop): resolve plugin SDK namespaces at call time - #107644
Closed
LisandroNahuelH wants to merge 1 commit into
Closed
LisandroNahuelH wants to merge 1 commit into
LisandroNahuelH wants to merge 1 commit into
Conversation
Every runtime (disk-door) desktop plugin fails to load: [plugins] runtime load failed (<id>) TypeError: Cannot convert undefined or null to object (…/app.asar.unpacked/dist/assets/sdk-*.js:5) An empty probe plugin fails identically, and the error points at the app's own chunk — plugin content is irrelevant. Root cause: inside the built `sdk` chunk, this module's section can evaluate BEFORE the section that assigns the `./index` namespace binding it reads (module cycle around sdk/index → contrib → runtime-loader → sdk/runtime preserved as concatenated sections; the namespace read is a hoisted `var` still `undefined` at that point). The module-level `GLOBALS` object then froze those `undefined` values, and the first shim built on plugin load died on `Object.keys(undefined)` — for every plugin, on every launch. Resolve the namespaces at CALL time (`sdkGlobals()` read by `installPluginSdk()` and the shim builder) instead of capturing them at module-eval time. Both call sites only run after boot, when every binding is assigned. No API change. Verified on a packaged Windows build (release/win-unpacked, Electron 40.10.2, desktop 0.17.2 / core v0.21.1): before, an instrumented shim builder logs `__HERMES_PLUGIN_SDK__` as `undefined` and the TypeError fires on first plugin load; after, all four namespaces log `object`, the import map builds, and plugins load with no `runtime load failed` lines and their statusbar chips rendering. Related: issue #107288 (same regression, same diagnosis); the same lazy-read shape is proposed in #107303 — submitted at the author's request as a minimal corroborating variant; maintainers should prefer whichever candidate they pick.
Contributor
This was referenced Sep 10, 2026
Contributor
|
Closing as a duplicate of #107303 (@g3org3yo, merged as 6c3d4a4 on 2026-09-10), which lands the same fix — Thanks for the independent diagnosis — the issue was real and the approach matched what merged. Credit for the fix goes to the earliest submitter per repo policy; if a follow-up gap surfaces in production builds, please open a fresh PR against current |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes every runtime (disk-door) desktop plugin failing to load after the recent bundle change:
Root cause: inside the built
sdkchunk,src/sdk/runtime.ts's module section can evaluate BEFORE the section that assigns the./indexnamespace binding it reads — the module cycle (sdk/index→contrib/*→contrib/runtime-loader→sdk/runtime) is preserved as concatenated sections, and the namespace read is a hoistedvarthat is stillundefinedat that point. The module-levelGLOBALSobject then froze thoseundefinedvalues, so the first shim built on plugin load died onObject.keys(undefined)— for every plugin, including a zero-import probe plugin (the error points at the app's own chunk, not plugin code).The fix resolves the namespaces at CALL time (
sdkGlobals()read byinstallPluginSdk()and the shim builder) instead of capturing them at module-eval time. Both call sites only run after boot, when every binding is assigned. Single file, no API change.Related Issue
Related: #107288 — same regression and same diagnosis (this intentionally does not claim uniqueness; see note above).
Type of Change
Changes Made
apps/desktop/src/sdk/runtime.ts: replace the module-levelGLOBALSconstant with asdkGlobals()accessor called byinstallPluginSdk()andshimUrl(), so the SDK/React namespaces are resolved at call time (post-boot) rather than captured during chunk evaluation.How to Test
Repro on base (any packaged build of current
main):$HERMES_HOME/desktop-plugins/<id>/plugin.js— an empty probe (export default { id: 'probe', register() {} }) is enough.logs/desktop.logshows[plugins] runtime load failed (…)pointing atsdk-*.js:5.Proof the fix works (packaged Windows build,
release/win-unpacked, Electron 40.10.2, desktop 0.17.2 / core v0.21.1):__HERMES_PLUGIN_SDK__ → undefinedand throws on the firstObject.keys; with this patch all four namespaces logobjectand the import map builds.release/win-unpacked): all runtime plugins load — noruntime load failedlines after boot — and the affected statusbar chips render.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass — N/A for this change: it is a desktop TypeScript-only change; the Python suite is untouched (CI runs the full matrix)release/win-unpackedbuild, Electron 40.10.2)Documentation & Housekeeping
runtime.tsdocuments the cycle and the lazy-read requirement)cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Before (base build, instrumented probe):
After (same probe, patched build):