{"record":{"id":"36f523ddf2aa8abe","repo":"projectdiscovery/nuclei","slug":"panic-occurred-while-executing-flow-v","errorCode":null,"errorMessage":"panic occurred while executing flow: %v","messagePattern":"panic occurred while executing flow: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tmplexec/flow/flow_executor.go","lineNumber":254,"sourceCode":"\t}()\n\tdefer func() {\n\t\t// remove set builtin\n\t\t_ = runtime.GlobalObject().Delete(\"set\")\n\t\t_ = runtime.GlobalObject().Delete(\"template\")\n\t\tfor proto := range f.protoFunctions {\n\t\t\t_ = runtime.GlobalObject().Delete(proto)\n\t\t}\n\t\truntime.RemoveContextValue(\"executionId\")\n\t}()\n\n\t// TODO(dwisiswant0): remove this once we get the RCA.\n\tdefer func() {\n\t\tif ci.IsCI() {\n\t\t\treturn\n\t\t}\n\n\t\tif r := recover(); r != nil {\n\t\t\tf.ctx.LogError(fmt.Errorf(\"panic occurred while executing flow: %v\", r))\n\t\t}\n\t}()\n\n\tif ctx.OnResult == nil {\n\t\treturn fmt.Errorf(\"output callback cannot be nil\")\n\t}\n\t// before running register set of builtins\n\tif err := runtime.Set(\"set\", func(call goja.FunctionCall) goja.Value {\n\t\tvarName := call.Argument(0).Export()\n\t\tvarValue := call.Argument(1).Export()\n\t\tf.options.GetTemplateCtx(f.ctx.Input.MetaInput).Set(types.ToString(varName), varValue)\n\t\treturn goja.Null()\n\t}); err != nil {\n\t\treturn err\n\t}\n\t// also register functions that allow executing protocols from js\n\tfor proto, fn := range f.protoFunctions {\n\t\tif err := runtime.Set(proto, fn); err != nil {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/tmplexec/flow/flow_executor.go#L236-L272","documentation":"A deferred recover inside FlowExecutor.Execute (pkg/tmplexec/flow/flow_executor.go:254, marked TODO for RCA) catches panics raised while the goja runtime executes the flow, logs them via ctx.LogError, and lets the scan continue. Notably the recover is skipped when running under CI (ci.IsCI()), so the same panic crashes the binary in CI — by design, to surface bugs there.","triggerScenarios":"Any runtime panic inside flow execution: nil map or nil pointer dereference in a protocol callback, an unexpected type crossing the JS/Go boundary in the flow runtime, or a bug in the flow engine itself. It fires only on the non-CLI-interactive path where a template with `flow:` executes against a target and something panics mid-program.","commonSituations":"A flow template exercising an engine edge case (nil template ctx value, exotic extractor output fed back into flow); upgrading templates without upgrading nuclei; SDK reuse of a template executer across goroutines it wasn't built for.","solutions":["Upgrade nuclei to the latest patch release — flow panic fixes land frequently","Reduce the template to the smallest flow that still panics (drop protocol sections one by one) and re-run to isolate the trigger","Run the repro in CI or with CI=true env to get a full goroutine dump instead of the recovered log line","Report the issue to projectdiscovery/nuclei with the template YAML, nuclei -version, and the panic value from the log"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The engine already recovers outside CI; at the call site keep per-template isolation:\nfunc runTemplateSafe(e protocols.Executer, ctx *scan.ScanContext) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"recovered flow panic: %v\", r)\n        }\n    }()\n    return e.Execute(ctx)\n}","preventionTips":["Run the newest nuclei patch release; flow panics get fixed quickly","Reproduce panics with CI=true to get a full stack instead of the one-line recovered log","Isolate flow templates in batch runners so one panic cannot stall the whole scan","Keep a known-good version pinned for production, test template updates in staging"],"tags":["flow","panic","goja","runtime","recovery"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}