{"record":{"id":"d51dd37d8974f235","repo":"projectdiscovery/nuclei","slug":"failed-to-compile-expression-q-w","errorCode":null,"errorMessage":"failed to compile expression %q: %w","messagePattern":"failed to compile expression %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/protocols/common/expressions/expressions.go","lineNumber":66,"sourceCode":"\n\t// replace simple placeholders (key => value) MarkerOpen + key + MarkerClose and General + key + General to value\n\tdata = replacer.Replace(data, base)\n\n\t// expressions can be:\n\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}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/protocols/common/expressions/expressions.go#L48-L84","documentation":"Runtime error from expressions.Evaluate (pkg/protocols/common/expressions/expressions.go:66). After simple placeholders are replaced, each remaining marker is treated as a govaluate expression and compiled with dsl.HelperFunctions. A syntactically invalid expression returns this error wrapping the govaluate failure and echoing the ORIGINAL marker text (originalExpression), so callers can pinpoint the bad template fragment.","triggerScenarios":"A {{...}} marker that is neither a simple variable nor a valid expression — e.g. '{{BaseURL} }' (bad spacing), '{{payload++}}' with stray operators, or a helper call with wrong arity like '{{md5()}}' (md5 expects 1 arg) — encountered while rendering raw requests, payloads, or flow steps.","commonSituations":"Fuzzing templates building arithmetic/string expressions from generator values; hand-authored markers with typos; DSL function signature drift after nuclei upgrades (renamed/arity-changed helpers); copy-paste of Go code into markers.","solutions":["Fix the marker syntax: balanced braces, valid operators, correct DSL helper arity (check `nuclei -dast` docs / dsl function list via `-h` or dsl.FunctionNames)","Pre-test expressions: put them in a `type: dsl` matcher/extractor and run `nuclei -validate -t template.yaml`","Keep complex logic in the DSL section rather than inline markers where possible","Quote string operands: \"'{{var}}' + 'x'\" rather than raw concatenation"],"exampleFix":"# before\n- raw:\n    - 'GET /{{path++}} HTTP/1.1'\n# after\n- raw:\n    - \"GET /{{path}} HTTP/1.1\"","handlingStrategy":"try-catch","validationCode":"import gvl \"github.com/projectdiscovery/govaluate\"\n\nfor _, expr := range expressions.FindExpressions(payloadOrRaw, \"{{\", \"}}\", data) {\n\tif _, err := gvl.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions); err != nil {\n\t\treturn fmt.Errorf(\"marker %q will fail to compile: %w\", expr, err)\n\t}\n}","typeGuard":"func markerExprCompiles(expr string) bool { _, err := govaluate.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions); return err == nil }","tryCatchPattern":"out, err := expressions.Evaluate(template, data)\nif err != nil && strings.Contains(err.Error(), \"failed to compile expression\") {\n\t// log original marker text (it is quoted in the error) and skip that request gracefully\n}","preventionTips":["Keep inline markers to simple variables; put logic in dsl: sections","Check DSL helper names/arity against the shipped version before upgrading","Validate templates with -validate and exercise fuzz templates against a local echo server"],"tags":["expressions","dsl","template","runtime","govaluate"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}