{"record":{"id":"c5c2840e9dfef68d","repo":"GopeedLab/gopeed","slug":"panic-v-c5c284","errorCode":null,"errorMessage":"panic: %v","messagePattern":"panic: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/download/engine/inject/vm/module.go","lineNumber":34,"sourceCode":"\t\truntime.Set(name, value)\n\t})\n}\n\nfunc (vm *Vm) Get(name string) (value any) {\n\tvm.loop.Run(func(runtime *goja.Runtime) {\n\t\tvalue = runtime.Get(name)\n\t})\n\treturn\n}\n\nfunc (vm *Vm) RunString(script string) (value any, err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tswitch v := r.(type) {\n\t\t\tcase error:\n\t\t\t\terr = v\n\t\t\tdefault:\n\t\t\t\terr = fmt.Errorf(\"panic: %v\", r)\n\t\t\t}\n\t\t}\n\t}()\n\n\tvm.loop.Run(func(runtime *goja.Runtime) {\n\t\tvalue, err = runtime.RunString(script)\n\t})\n\treturn\n}\n\nfunc Enable(runtime *goja.Runtime) error {\n\treturn runtime.Set(\"__gopeed_create_vm\", func(call goja.FunctionCall) goja.Value {\n\t\treturn runtime.ToValue(&Vm{\n\t\t\tloop: eventloop.NewEventLoop(),\n\t\t})\n\t})\n}\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/GopeedLab/gopeed/blob/7b7327ffb30816273a74b142cccc0bc10c5a4c67/pkg/download/engine/inject/vm/module.go#L16-L52","documentation":"Vm.RunString executes a script string inside a VM created by the __gopeed_create_vm binding, under an event loop and a deferred recover. The 'panic: %v' fallback fires when the recovered value is neither an error nor anything else handled — here the switch only has an error case, so ANY non-error panic (including goja.Value) renders as 'panic: %v'. It means native code or the runtime panicked while running the script.","triggerScenarios":"RunString on a script that invokes a host binding which panics with a string; running a script after the VM's event loop was stopped; goja internal panics on pathological input (e.g. stack overflow from infinite recursion appears as a runtime error, but custom panics land here).","commonSituations":"Extensions embedding sandboxed helper scripts via the vm module; scripts assuming globals that were never installed in the VM; reusing a Vm across loop shutdowns.","solutions":["Check the script for calls into host bindings and validate their arguments before invoking","Prefer checking err from RunString and logging both value and err to isolate whether the script itself is malformed","Recreate the VM instead of reusing one whose loop may have been stopped"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"value, err := vm.RunString(script)\nif err != nil {\n    if strings.Contains(err.Error(), \"panic:\") {\n        // native/runtime panic inside the VM: do not reuse this VM instance\n        return fmt.Errorf(\"vm script panicked: %w\", err)\n    }\n    return fmt.Errorf(\"vm script failed: %w\", err)\n}","preventionTips":["Create a fresh Vm per script run rather than reusing one across lifecycle events","Install all globals the script expects before RunString","Lint embedded scripts (syntax check) before passing them to the VM"],"tags":["goja","javascript","panic","vm","sandbox"],"backgroundTag":null,"analyzedSha":"7b7327ffb30816273a74b142cccc0bc10c5a4c67","analyzedAt":"2026-08-16T02:51:03.250Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}