{"record":{"id":"7c1df54fc58bfc86","repo":"projectdiscovery/nuclei","slug":"exportas-expects-2-arguments","errorCode":null,"errorMessage":"ExportAs expects 2 arguments","messagePattern":"ExportAs expects 2 arguments","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/js/compiler/pool.go","lineNumber":195,"sourceCode":"\t\t\t}\n\t\t\tfor _, arg := range call.Arguments {\n\t\t\t\tif out := stringify(arg, runtime); out != \"\" {\n\t\t\t\t\tbuff.WriteString(out)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn goja.Null()\n\t\t},\n\t})\n\t// register exportAs function\n\t_ = gojs.RegisterFuncWithSignature(runtime, gojs.FuncOpts{\n\t\tName:        \"ExportAs\", // Export\n\t\tSignatures:  []string{\"ExportAs(key string,value any)\"},\n\t\tDescription: \"Exports given value with specified key and makes it available in DSL and response\",\n\t\tFuncDecl: func(call goja.FunctionCall, runtime *goja.Runtime) goja.Value {\n\t\t\tif len(call.Arguments) != 2 {\n\t\t\t\t// this is how goja expects errors to be returned\n\t\t\t\t// and internally it is done same way for all errors\n\t\t\t\tpanic(runtime.ToValue(\"ExportAs expects 2 arguments\"))\n\t\t\t}\n\t\t\tkey := call.Argument(0).String()\n\t\t\tvalue := call.Argument(1)\n\t\t\topts.exports[key] = stringify(value, runtime)\n\t\t\treturn goja.Null()\n\t\t},\n\t})\n}\n\n// Internal purposes i.e generating bindings\nfunc InternalGetGeneratorRuntime() *goja.Runtime {\n\truntime := gojapool.Get().(*goja.Runtime)\n\treturn runtime\n}\n\nfunc enableRequire(runtime *goja.Runtime) {\n\tlazyRegistryInit()\n\t_ = require.NewRegistry(require.WithLoader(newSourceLoader(runtime))).Enable(runtime)","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/compiler/pool.go#L177-L213","documentation":"A JavaScript (code protocol) template called the registered helper ExportAs with an argument count other than 2. The binding registered on the goja runtime explicitly panics with this message when len(call.Arguments) != 2; goja converts that panic into a JS exception, aborting template compilation/execution. The expected signature is ExportAs(key string, value any).","triggerScenarios":"Template JS calling ExportAs('k') with no value, ExportAs() with nothing, or ExportAs('k', v, extra); also passing extra undefined trailing arguments, since goja counts supplied arguments.","commonSituations":"Hand-writing code-protocol templates and forgetting the value; refactoring a helper into ExportAs and leaving an old single-argument call; copy-paste from examples that used a different export API.","solutions":["Call ExportAs with exactly two arguments: a string key and any value, e.g. ExportAs('extracted', value).","Lint template JS early — a syntax/arity check via the code protocol compile step (template-validate) catches it before a scan run.","If you meant to export several values, issue one ExportAs call per key/value pair."],"exampleFix":"// before\nExportAs('token'); // -> ExportAs expects 2 arguments\n\n// after\nExportAs('token', extractedValue);","handlingStrategy":"validation","validationCode":"// in template JS: keep the arity check on your side\nif (typeof key === 'string' && value !== undefined) {\n    ExportAs(key, value);\n}","typeGuard":"// JS guard before calling\nconst exportAs = (k, v) => { if (arguments.length !== 2) throw new TypeError('ExportAs(key, value)'); ExportAs(k, v); };","tryCatchPattern":"try { ExportAs('k', v); } catch (e) { if (String(e).includes('expects 2 arguments')) { /* fix call site arity */ } }","preventionTips":["ExportAs takes exactly (key, value) — one call per exported value.","template-validate / lint code templates before scanning.","Count arguments you pass, including trailing undefined ones."],"tags":["javascript","goja","templates","code-protocol","arity"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}