{"record":{"id":"c3bfe21b468a801b","repo":"projectdiscovery/nuclei","slug":"no-templates-provided-for-scan","errorCode":null,"errorMessage":"no templates provided for scan","messagePattern":"no templates provided for scan","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/runner/runner.go","lineNumber":926,"sourceCode":"\treturn result, nil\n}\n\nfunc (r *Runner) executeTemplatesInput(store *loader.Store, engine *core.Engine) (*atomic.Bool, error) {\n\tif r.options.VerboseVerbose {\n\t\tfor _, template := range store.Templates() {\n\t\t\tr.logAvailableTemplate(template.Path)\n\t\t}\n\t\tfor _, template := range store.Workflows() {\n\t\t\tr.logAvailableTemplate(template.Path)\n\t\t}\n\t}\n\n\tfinalTemplates := []*templates.Template{}\n\tfinalTemplates = append(finalTemplates, store.Templates()...)\n\tfinalTemplates = append(finalTemplates, store.Workflows()...)\n\n\tif len(finalTemplates) == 0 {\n\t\treturn nil, errors.New(\"no templates provided for scan\")\n\t}\n\n\t// pass input provider to engine\n\t// TODO: this should be not necessary after r.hmapInputProvider is removed + refactored\n\tif r.inputProvider == nil {\n\t\treturn nil, errors.New(\"no input provider found\")\n\t}\n\tresults := engine.ExecuteScanWithOpts(context.Background(), finalTemplates, r.inputProvider, r.options.DisableClustering)\n\treturn results, nil\n}\n\n// displayExecutionInfo prints parser stats, version info, and scan counts.\nfunc (r *Runner) displayExecutionInfo(store *loader.Store) {\n\t// Display parser stats for templates loaded into the store.\n\tstats.Display(templates.TemplateSyntaxWarningStats)\n\tstats.Display(templates.TemplateSyntaxErrorStats)\n\tstats.Display(templates.TemplateRuntimeWarningStats)\n","sourceCodeStart":908,"sourceCodeEnd":944,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/internal/runner/runner.go#L908-L944","documentation":"readSMBFile refuses inputs whose resolved SMB path is the share root (Path == \".\") or that isDirectorySMBTarget flags as a directory. The file protocol only elaborates regular files, so directory inputs get a clean error instead of attempting a directory read over SMB.","triggerScenarios":"Passing \\\\server\\share or \\\\server\\share\\folder (or smb://host/share/) as a file-protocol target; directory entries from an SMB listing fed back unfiltered.","commonSituations":"Target lists containing share roots; walking SMB enumerations without filtering; assuming nuclei recurses into SMB directories.","solutions":["Point at a concrete file: \\\\server\\share\\docs\\report.pdf","Filter listing output so only regular files reach nuclei","Enumerate first, then scan each file path individually"],"exampleFix":"# before\n\\\\server\\share\n# after\n\\\\server\\share\\docs\\report.pdf","handlingStrategy":"validation","validationCode":"import \"strings\"\n\n// A file target needs at least host/share/file depth; host/share alone is a share root.\nfunc namesSMBFile(s string) bool {\n    t := strings.TrimSpace(s)\n    lower := strings.ToLower(t)\n    if !strings.HasPrefix(lower, \"smb://\") {\n        lower = strings.TrimPrefix(lower, \"smb://\")\n    }\n    p := strings.Trim(strings.ReplaceAll(lower, \"\\\\\", \"/\"), \"/\")\n    if p == t || p == \"\" {\n        return false\n    }\n    return len(strings.Split(p, \"/\")) >= 3\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Append explicit file names to SMB targets","Filter directory entries from listings before scanning","Treat share roots as enumeration inputs, not file inputs"],"tags":["smb","file","path"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}