{"record":{"id":"cb26cf316007695d","repo":"projectdiscovery/nuclei","slug":"failed-to-evaluate-expression-q-w","errorCode":null,"errorMessage":"failed to evaluate expression %q: %w","messagePattern":"failed to evaluate expression %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/protocols/common/expressions/expressions.go","lineNumber":71,"sourceCode":"\t// - simple: containing base values keys (variables)\n\t// - complex: containing helper functions [ + variables]\n\t// literals like {{2+2}} are not considered expressions\n\tfor _, expression := range expressions {\n\t\toriginalExpression := expression\n\t\t// data has already had simple placeholders replaced; keep the same\n\t\t// marker shape for output replacement, but never compile this string.\n\t\treplacedExpression := replacer.Replace(expression, base)\n\t\texpression = replaceStringPlaceholders(expression, base)\n\n\t\t// turns expressions (either helper functions+base values or base values)\n\t\tcompiled, err := govaluate.NewEvaluableExpressionWithFunctions(expression, dsl.HelperFunctions)\n\t\tif err != nil {\n\t\t\treturn data, fmt.Errorf(\"failed to compile expression %q: %w\", originalExpression, err)\n\t\t}\n\n\t\tresult, err := compiled.Evaluate(base)\n\t\tif err != nil {\n\t\t\treturn data, fmt.Errorf(\"failed to evaluate expression %q: %w\", originalExpression, err)\n\t\t}\n\n\t\treplacement := result\n\t\t// Preserve unresolved markers only when a helper call would otherwise\n\t\t// hide them from downstream validation. Plain expressions such as\n\t\t// comparisons should evaluate normally.\n\t\tif markers := unresolvedVarMarkers(compiled.Vars(), base); markers != \"\" {\n\t\t\tusesFunctions := false\n\t\t\tfor _, token := range compiled.Tokens() {\n\t\t\t\tif token.Kind == govaluate.FUNCTION {\n\t\t\t\t\tusesFunctions = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif usesFunctions && ContainsUnresolvedVariables(fmt.Sprint(result)) == nil {\n\t\t\t\treplacement = markers\n\t\t\t}\n\t\t}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/protocols/common/expressions/expressions.go#L53-L89","documentation":"Runtime error from expressions.Evaluate (pkg/protocols/common/expressions/expressions.go:71). The expression compiled fine (govaluate.NewEvaluableExpressionWithFunctions succeeded) but compiled.Evaluate(base) failed — typically because a referenced variable is missing from the base data map or a helper function errored at runtime (e.g. bad argument type). The error wraps the govaluate failure and names the original expression.","triggerScenarios":"'{{randstr(1)}}' with wrong arg type, '{{undefined_var}} == 1' where undefined_var is absent from data (this path fires when it compiled as an identifier but no value exists at eval), or a DSL helper whose runtime input is malformed (e.g. to_number('abc')).","commonSituations":"Flow/fuzz templates referencing extractor outputs that a skipped request never produced; marker variables whose names drift from the generator's payload names (payloads vs payload); helper functions receiving nil after an upstream extraction failure.","solutions":["Verify every identifier in the expression is present in the data map at evaluation time (generator payload names, extractor names with internal:true, or built-ins like BaseURL)","Check DSL helper arity/types against the docs and sanitize inputs (e.g. to_string before to_number)","Give extractors fallbacks or gate dependent requests with matchers so variables always exist before use","Reproduce with -v and print the base map to see which key is missing"],"exampleFix":"# before\n- raw:\n    - 'X-Token: {{token}}'\n  # token never extracted when first request fails\n# after\nmatchers:\n  - type: word\n    words:\n      - 'session'\n    internal: true\n# (ensure the producing request matched, so {{token}} exists downstream)","handlingStrategy":"try-catch","validationCode":"// before evaluating, confirm every identifier the expression uses is present\nfor _, v := range compiled.Vars() {\n\tif _, ok := data[v]; !ok {\n\t\treturn fmt.Errorf(\"variable %q missing; skip or provide default before evaluation\", v)\n\t}\n}","typeGuard":"func allVarsPresent(expr string, data map[string]interface{}) bool {\n\tc, err := govaluate.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions)\n\tif err != nil { return false }\n\tfor _, v := range c.Vars() { if _, ok := data[v]; !ok { return false } }\n\treturn true\n}","tryCatchPattern":"out, err := expressions.Evaluate(tplText, data)\nif err != nil && strings.Contains(err.Error(), \"failed to evaluate expression\") {\n\t// missing runtime variable: skip request, or substitute defaults and retry once\n}","preventionTips":["Guarantee producer requests matched before consumers reference their extractor outputs","Name generator payloads exactly as referenced in markers","Use -v to dump the data map when reproducing","Give optional values defaults so identifiers never evaluate undefined"],"tags":["expressions","dsl","variables","template","runtime"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}