{"record":{"id":"c44ed093db6a41a0","repo":"siyuan-note/siyuan","slug":"goja-panic-during-event-loop-run-v","errorCode":null,"errorMessage":"goja panic during event loop run: %v","messagePattern":"goja panic during event loop run: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/plugin/plugin.go","lineNumber":192,"sourceCode":"\t})\n\tp.agentCapabilities.Clear()\n}\n\n// updateState updates the plugin state atomically and pushes the new state to the frontend via util.PushKernelPluginState.\nfunc (p *KernelPlugin) updateState(state PluginState) {\n\tp.state.Store(int64(state))\n\tutil.PushKernelPluginState(p.Name, int(state))\n}\n\n// InitRuntime initializes the goja runtime and evaluates kernel.js.\nfunc (p *KernelPlugin) InitRuntime() (err error) {\n\tp.runtime = eventloop.NewEventLoop(eventloop.EnableConsole(true))\n\tp.worker.Start(p.runtime)\n\n\tp.runtime.Run(func(rt *goja.Runtime) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\terr = fmt.Errorf(\"goja panic during event loop run: %v\", r)\n\t\t\t}\n\t\t}()\n\n\t\t// Use JSON struct tags for field name mapping, with fallback to original names if \"json\" tag is absent.\n\t\trt.SetFieldNameMapper(goja.TagFieldNameMapper(\"json\", true))\n\n\t\tif enableErr := EnableExtendModules(p, rt); enableErr != nil {\n\t\t\terr = fmt.Errorf(\"EnableExtendModules: %v\", enableErr)\n\t\t\treturn\n\t\t}\n\n\t\tif enableErr := EnableSiyuanModule(p, rt); enableErr != nil {\n\t\t\terr = fmt.Errorf(\"EnableSiyuanModule: %v\", enableErr)\n\t\t\treturn\n\t\t}\n\n\t\tif _, runErr := rt.RunScript(p.file, p.Kernel.JS); runErr != nil {\n\t\t\terr = fmt.Errorf(\"RunScript: %v\", runErr)","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/plugin/plugin.go#L174-L210","documentation":"During plugin startup, `InitRuntime` runs a setup function inside the plugin's goja event loop. A Go-level panic raised anywhere in that setup (field-name mapper installation, module registration, etc.) is recovered and reported as `goja panic during event loop run: %v`. This is a fatal plugin initialization failure — the plugin's runtime never gets its modules or script loaded.","triggerScenarios":"A panic inside the `rt.Run(func(rt *goja.Runtime){...})` body during `InitRuntime` — typically a nil pointer or lo.Must assertion failure while registering extend/siyuan modules, before the Enable* wrappers convert their own errors.","commonSituations":"A kernel build with mismatched goja/eventloop versions, a plugin descriptor (Kernel.JS) that is nil or malformed causing script access panics, or concurrent start/stop of the same plugin racing on the runtime.","solutions":["Read the panic value in the message to find the nil/invalid value source in the kernel code","Verify the plugin's kernel.js content was downloaded/loaded intact (not empty or truncated)","Restart the plugin (disable then enable) to rule out a transient race during start","Update SiYuan; if reproducible, file an issue with the panic message and plugin name"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := plugin.Start(); err != nil { log.Warnf(\"plugin failed to init: %v; skipping\", err) }","preventionTips":["Avoid rapid enable/disable cycles on plugins","Verify plugin packages download completely (check kernel.js is non-empty)","Keep SiYuan updated so goja/eventloop stay in sync","Watch kernel logs at startup for the first failing plugin"],"tags":["goja","panic-recovery","plugin-lifecycle","runtime"],"backgroundTag":"module-init-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}