{"record":{"id":"a98d9a197118f69f","repo":"projectdiscovery/nuclei","slug":"unresolved-variables-found-s","errorCode":null,"errorMessage":"unresolved variables found: %s","messagePattern":"unresolved variables found: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/protocols/common/expressions/variables.go","lineNumber":41,"sourceCode":"\t\t\treturn nil\n\t\t}\n\t\tvar unresolvedVariables []string\n\t\tfor _, match := range matches {\n\t\t\tif len(match) < 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Skip if the match is an expression\n\t\t\tif numericalExpressionRegex.MatchString(match[1]) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// or if it contains only literals (can be solved from expression engine)\n\t\t\tif hasLiteralsOnly(match[1]) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tunresolvedVariables = append(unresolvedVariables, match[1])\n\t\t}\n\t\tif len(unresolvedVariables) > 0 {\n\t\t\treturn errors.New(\"unresolved variables found: \" + strings.Join(unresolvedVariables, \",\"))\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ContainsVariablesWithNames returns an error with variable names if the passed\n// input contains unresolved {{<pattern-here>}} variables within the provided list\nfunc ContainsVariablesWithNames(names map[string]interface{}, items ...string) error {\n\tfor _, data := range items {\n\t\tmatches := unresolvedVariablesRegex.FindAllStringSubmatch(data, -1)\n\t\tif len(matches) == 0 {\n\t\t\treturn nil\n\t\t}\n\t\tvar unresolvedVariables []string\n\t\tfor _, match := range matches {\n\t\t\tif len(match) < 2 {\n\t\t\t\tcontinue","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/protocols/common/expressions/variables.go#L23-L59","documentation":"Raised by the unresolved-variable checker in pkg/protocols/common/expressions (variables.go:41). It scans each input string for {{...}} markers; matches that are pure arithmetic expressions or literal-only govaluate expressions (resolvable by the DSL engine) are skipped, and every remaining {{name}} is collected. If any remain, it returns 'unresolved variables found: a,b' so the caller knows which markers would be sent literally.","triggerScenarios":"A raw HTTP request body containing {{username}} with no payload, variables or flow value defining 'username'; a path like /api/{{version}}/user where version is never set.","commonSituations":"Template refactor removes a variables block but leaves the marker; marker name typo relative to the payload key ({{usr}} vs payload 'user'); copying a raw request from Burp that contains templated-looking braces.","solutions":["Define the value in the template's variables block, payloads, or a preceding flow/extract step","Fix the marker name so it exactly matches the payload/variable key","For literal braces that are not placeholders, keep the content literal-only or arithmetic so the checker can resolve or skip it"],"exampleFix":"# before\nhttp:\n  - raw:\n      - 'GET /api/{{version}}/user HTTP/1.1'\n# after\nhttp:\n  - raw:\n      - 'GET /api/{{version}}/user HTTP/1.1'\n    variables:\n      version: 'v2'","handlingStrategy":"validation","validationCode":"if err := expressions.ContainsUnresolvedVariables(rawRequest, headers...); err != nil {\n    return fmt.Errorf(\"fix template before run: %w\", err)\n}","typeGuard":"func hasUnresolvedVariables(err error) bool { return strings.HasPrefix(err.Error(), \"unresolved variables found:\") }","tryCatchPattern":"err := expressions.ContainsUnresolvedVariables(items...)\nif err != nil { names := strings.Split(strings.TrimPrefix(err.Error(), \"unresolved variables found: \"), \",\") /* map names back to missing definitions */ }","preventionTips":["Run the unresolved-variable check in template lint CI","Name payloads and markers identically (single source of truth)","Keep literals inside DSL expressions so the engine can resolve them"],"tags":["template","variables","dsl","validation"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}