{"record":{"id":"18596e4fe74afda6","repo":"projectdiscovery/nuclei","slug":"empty-operators","errorCode":null,"errorMessage":"empty operators","messagePattern":"empty operators","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/protocols/file/file.go","lineNumber":140,"sourceCode":"\t\"raw,body,all,data\": \"Raw contains the raw file contents\",\n}\n\n// defaultDenylist contains common extensions to exclude\nvar defaultDenylist = []string{\".3g2\", \".3gp\", \".arj\", \".avi\", \".axd\", \".bmp\", \".css\", \".csv\", \".deb\", \".dll\", \".doc\", \".drv\", \".eot\", \".exe\", \".flv\", \".gif\", \".gifv\", \".h264\", \".ico\", \".iso\", \".jar\", \".jpeg\", \".jpg\", \".lock\", \".m4a\", \".m4v\", \".map\", \".mkv\", \".mov\", \".mp3\", \".mp4\", \".mpeg\", \".mpg\", \".msi\", \".ogg\", \".ogm\", \".ogv\", \".otf\", \".pdf\", \".pkg\", \".png\", \".ppt\", \".psd\", \".rm\", \".rpm\", \".svg\", \".swf\", \".sys\", \".tif\", \".tiff\", \".ttf\", \".vob\", \".wav\", \".webm\", \".wmv\", \".woff\", \".woff2\", \".xcf\", \".xls\", \".xlsx\"}\n\n// defaultArchiveDenyList contains common archive extensions to exclude\nvar defaultArchiveDenyList = []string{\".7z\", \".apk\", \".gz\", \".rar\", \".tar.gz\", \".tar\", \".zip\"}\n\n// GetID returns the unique ID of the request if any.\nfunc (request *Request) GetID() string {\n\treturn request.ID\n}\n\n// Compile compiles the protocol request for further execution.\nfunc (request *Request) Compile(options *protocols.ExecutorOptions) error {\n\t// if there are no matchers/extractors, we trigger an error as no operation would be performed on the template\n\tif request.IsEmpty() {\n\t\treturn errors.New(\"empty operators\")\n\t}\n\tcompiled := &request.Operators\n\tcompiled.ExcludeMatchers = options.ExcludeMatchers\n\tcompiled.TemplateID = options.TemplateID\n\tif err := compiled.Compile(); err != nil {\n\t\treturn errors.Wrap(err, \"could not compile operators\")\n\t}\n\trequest.CompiledOperators = compiled\n\n\t// By default, use default max size if not defined\n\tswitch {\n\tcase request.MaxSize != \"\":\n\t\tmaxSize, err := units.FromHumanSize(request.MaxSize)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"could not compile operators\")\n\t\t}\n\t\trequest.maxSize = maxSize\n\tcase request.MaxSize == \"no\":","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/protocols/file/file.go#L122-L158","documentation":"Returned by Compile in the file protocol when the request has no matchers and no extractors (IsEmpty() is true). Every nuclei protocol requires at least one operator, otherwise the file would be read and nothing evaluated against it. The error surfaces at template load/compile time, so the template is rejected before any scanning starts.","triggerScenarios":"A template with a `file:` protocol request block that lacks both a `matchers:` and an `extractors:` section. Also produced when YAML indentation accidentally places matchers at template top level instead of inside the requests block.","commonSituations":"Converting a grep/find one-liner into a file template and forgetting the matcher; indentation mistakes when hand-editing YAML; beginners assuming file presence alone is a detectable condition.","solutions":["Add at least one matcher (e.g. word/regex on file content) or extractor to the file request","Run `nuclei -t your-template.yaml -validate` to catch it before scanning","Check YAML indentation so matchers/extractors sit inside the file request block, not at template root"],"exampleFix":"# before\nfile:\n  - extensions:\n      - all\n\n# after\nfile:\n  - extensions:\n      - all\n    matchers:\n      - type: word\n        words:\n          - \"PRIVATE KEY\"","handlingStrategy":"validation","validationCode":"// template-side check before executing\nif len(req.Matchers) == 0 && len(req.Extractors) == 0 {\n    return fmt.Errorf(\"file request %s has empty operators\", req.ID)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run `nuclei -t template.yaml -validate` after writing or editing file-protocol templates","Treat every protocol request as needing at least one matcher or extractor by design","Lint YAML indentation — matchers must sit inside the file request block"],"tags":["file-protocol","template","validation","operators"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}