{"record":{"id":"74e9f072cf23048f","repo":"siyuan-note/siyuan","slug":"failed-to-inject-global-context-v","errorCode":null,"errorMessage":"failed to inject global context: %v","messagePattern":"failed to inject global context: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/sandbox.go","lineNumber":101,"sourceCode":"\tregistry := require.NewRegistry()\n\n\tregistry.Enable(rt)\n\tregistry.RegisterNativeModule(\n\t\tconsole.ModuleName,\n\t\tconsole.RequireWithPrinter(&Printer{name: p.Name}),\n\t)\n\n\turl.Enable(rt)\n\tbuffer.Enable(rt)\n\tconsole.Enable(rt)\n\treturn\n}\n\n// EnableSiyuanModule injects all siyuan.* APIs into the plugin's goja global context.\nfunc EnableSiyuanModule(p *KernelPlugin, rt *goja.Runtime) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"failed to inject global context: %v\", r)\n\t\t}\n\t}()\n\n\tsiyuan := rt.NewObject()\n\n\tlo.Must0(injectPlugin(p, rt, siyuan))\n\tlo.Must0(injectEvent(p, rt, siyuan))\n\tlo.Must0(injectLogger(p, rt, siyuan))\n\tlo.Must0(injectStorage(p, rt, siyuan))\n\tlo.Must0(injectRpc(p, rt, siyuan))\n\tlo.Must0(injectAgent(p, rt, siyuan))\n\tlo.Must0(injectClient(p, rt, siyuan))\n\tlo.Must0(injectServer(p, rt, siyuan))\n\tlo.Must0(injectSecretsVars(p, rt, siyuan))\n\n\tlo.Must0(ObjectFreeze(rt, siyuan))\n\n\tlo.Must0(rt.GlobalObject().Set(\"siyuan\", siyuan))","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/sandbox.go#L83-L119","documentation":"EnableSiyuanModule injects the global siyuan.* API surface into the plugin's goja runtime. Any panic during injection (object creation, injector functions like injectPlugin, etc.) is recovered and wrapped into this error.","triggerScenarios":"Calling EnableSiyuanModule when one of the inject helpers (injectPlugin, event/network/etc. injections) panics — typically due to a nil runtime, nil KernelPlugin, a lo.Must0 assertion failing inside injection, or a runtime interrupted mid-injection.","commonSituations":"Plugin bootstrap against a runtime already killed by a script timeout; a nil *KernelPlugin pointer passed in; an injected API registration that hits a nil map or failed assertion inside lo.Must0.","solutions":["Read the wrapped panic text (%v) to identify which injector panicked","Ensure both p *KernelPlugin and rt *goja.Runtime are non-nil and the runtime is fresh/not interrupted","Check lo.Must0-asserted calls inside the injection path for conditions that can fail","Fail the plugin load on this error rather than reusing the runtime","Review recent changes to siyuan API injectors for panicking code paths"],"exampleFix":"// before\nrt := goja.New()\nrt.Interrupt(\"timeout\")\nerr := EnableSiyuanModule(p, rt) // panics inside -> wrapped error\n// after\nrt := goja.New()\nerr := EnableSiyuanModule(p, rt)","handlingStrategy":"try-catch","validationCode":"if p == nil || rt == nil {\n    return fmt.Errorf(\"EnableSiyuanModule requires non-nil plugin and runtime\")\n}","typeGuard":null,"tryCatchPattern":"if err := EnableSiyuanModule(p, rt); err != nil {\n    return fmt.Errorf(\"siyuan module injection failed for %s: %w\", p.Name, err)\n}","preventionTips":["Run EnableSiyuanModule immediately after runtime creation, before any script execution","Ensure no injector uses lo.Must0 on conditions that can legitimately fail","Verify runtime was not interrupted by a prior timeout","Treat this error as fatal for the plugin's sandbox and rebuild the runtime"],"tags":["goja","javascript","plugin-sandbox","panic-recovery"],"backgroundTag":"module-init-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}