{"record":{"id":"88e2d85f053fae8a","repo":"projectdiscovery/nuclei","slug":"unknown-matcher-type-specified-s","errorCode":null,"errorMessage":"unknown matcher type specified: %s","messagePattern":"unknown matcher type specified: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/operators/matchers/compile.go","lineNumber":30,"sourceCode":")\n\n// CompileMatchers performs the initial setup operation on a matcher\nfunc (matcher *Matcher) CompileMatchers() error {\n\tvar ok bool\n\n\t// Support hexadecimal encoding for matchers too.\n\tif matcher.Encoding == \"hex\" {\n\t\tfor i, word := range matcher.Words {\n\t\t\tif decoded, err := hex.DecodeString(word); err == nil && len(decoded) > 0 {\n\t\t\t\tmatcher.Words[i] = string(decoded)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set up the matcher type\n\tcomputedType, err := toMatcherTypes(matcher.GetType().String())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unknown matcher type specified: %s\", matcher.Type)\n\t}\n\n\tmatcher.matcherType = computedType\n\n\t// Validate the matcher structure\n\tif err := matcher.Validate(); err != nil {\n\t\treturn err\n\t}\n\n\t// By default, match on body if user hasn't provided any specific items\n\tif matcher.Part == \"\" && matcher.GetType() != DSLMatcher {\n\t\tmatcher.Part = \"body\"\n\t}\n\n\t// Compile the regexes (with shared cache)\n\tfor _, regex := range matcher.Regex {\n\t\tif cached, err := cache.Regex().GetIFPresent(regex); err == nil && cached != nil {\n\t\t\tmatcher.regexCompiled = append(matcher.regexCompiled, cached)","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/operators/matchers/compile.go#L12-L48","documentation":"Template compilation error from Matcher.CompileMatchers (pkg/operators/matchers/compile.go:30). The matcher's `type:` is mapped via toMatcherTypes, which normalizes (trim+lowercase) and compares against {status, size, word, regex, binary, dsl, xpath}. Any other value — including a missing `type:` (zero-value String() is \"\") — fails here. Note the singular form: `word`, not `words`.","triggerScenarios":"`type: words` (plural), `type: Status` alone is fine (normalized) but `type: status-code`, `type: header`, or a missing/misspelled type fails; also matcher blocks whose YAML indentation detaches `type:` from the matcher map.","commonSituations":"Writing `words:` field with `type: words` by symmetry; templates ported from other scanners with different type vocabularies; YAML list/indent mistakes that drop the type key during unmarshal.","solutions":["Use exactly one of: status, size, word, regex, binary, dsl, xpath (singular 'word')","Fix indentation so `type:` is a sibling of the matcher's other keys","Validate with `nuclei -validate -t template.yaml` or `make template-validate`","When embedding via SDK, print matcher.Type — the error includes the raw string"],"exampleFix":"# before\nmatchers:\n  - type: words\n    words:\n      - 'admin'\n# after\nmatchers:\n  - type: word\n    words:\n      - 'admin'","handlingStrategy":"validation","validationCode":"var validMatcherTypes = map[string]bool{\"status\": true, \"size\": true, \"word\": true, \"regex\": true, \"binary\": true, \"dsl\": true, \"xpath\": true}\n\nfunc matcherTypeOK(t string) bool { return validMatcherTypes[strings.ToLower(strings.TrimSpace(t))] }","typeGuard":"type MatcherSpec struct{ Type string; Words []string; Regex []string; Status []int }\n\nfunc (m MatcherSpec) Valid() bool { return matcherTypeOK(m.Type) }","tryCatchPattern":"if err := m.CompileMatchers(); err != nil {\n\tif strings.HasPrefix(err.Error(), \"unknown matcher type\") {\n\t\t// author error: echo template path + allowed type list\n\t}\n\treturn err\n}","preventionTips":["It's 'word', not 'words'; status/size are singular concepts too","Run nuclei -validate in template CI","Generate matchers from typed structs; avoid hand-typed maps"],"tags":["matcher","template","compile-time","yaml","validation"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}