projectdiscovery/nuclei · error

failed to compile expression %q: %w

Error message

failed to compile expression %q: %w

What it means

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.

Source

Thrown at pkg/protocols/common/expressions/expressions.go:66

	// replace simple placeholders (key => value) MarkerOpen + key + MarkerClose and General + key + General to value
	data = replacer.Replace(data, base)

	// expressions can be:
	// - simple: containing base values keys (variables)
	// - complex: containing helper functions [ + variables]
	// literals like {{2+2}} are not considered expressions
	for _, expression := range expressions {
		originalExpression := expression
		// data has already had simple placeholders replaced; keep the same
		// marker shape for output replacement, but never compile this string.
		replacedExpression := replacer.Replace(expression, base)
		expression = replaceStringPlaceholders(expression, base)

		// turns expressions (either helper functions+base values or base values)
		compiled, err := govaluate.NewEvaluableExpressionWithFunctions(expression, dsl.HelperFunctions)
		if err != nil {
			return data, fmt.Errorf("failed to compile expression %q: %w", originalExpression, err)
		}

		result, err := compiled.Evaluate(base)
		if err != nil {
			return data, fmt.Errorf("failed to evaluate expression %q: %w", originalExpression, err)
		}

		replacement := result
		// Preserve unresolved markers only when a helper call would otherwise
		// hide them from downstream validation. Plain expressions such as
		// comparisons should evaluate normally.
		if markers := unresolvedVarMarkers(compiled.Vars(), base); markers != "" {
			usesFunctions := false
			for _, token := range compiled.Tokens() {
				if token.Kind == govaluate.FUNCTION {
					usesFunctions = true
					break
				}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Fix the marker syntax: balanced braces, valid operators, correct DSL helper arity (check `nuclei -dast` docs / dsl function list via `-h` or dsl.FunctionNames)
  2. Pre-test expressions: put them in a `type: dsl` matcher/extractor and run `nuclei -validate -t template.yaml`
  3. Keep complex logic in the DSL section rather than inline markers where possible
  4. Quote string operands: "'{{var}}' + 'x'" rather than raw concatenation

Example fix

# before
- raw:
    - 'GET /{{path++}} HTTP/1.1'
# after
- raw:
    - "GET /{{path}} HTTP/1.1"
Defensive patterns

Strategy: try-catch

Validate before calling

import gvl "github.com/projectdiscovery/govaluate"

for _, expr := range expressions.FindExpressions(payloadOrRaw, "{{", "}}", data) {
	if _, err := gvl.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions); err != nil {
		return fmt.Errorf("marker %q will fail to compile: %w", expr, err)
	}
}

Type guard

func markerExprCompiles(expr string) bool { _, err := govaluate.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions); return err == nil }

Try / catch

out, err := expressions.Evaluate(template, data)
if err != nil && strings.Contains(err.Error(), "failed to compile expression") {
	// log original marker text (it is quoted in the error) and skip that request gracefully
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/d51dd37d8974f235. Report an issue: GitHub.