{"record":{"id":"088cb7811a4464e7","repo":"projectdiscovery/nuclei","slug":"unsupported-input-mode-s","errorCode":null,"errorMessage":"unsupported input mode: %s","messagePattern":"unsupported input mode: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/input/provider/interface.go","lineNumber":146,"sourceCode":"\n\t\t\t// Get HttpClient from protocolstate if available\n\t\t\tvar httpClient *retryablehttp.Client\n\t\t\tif opts.Options.ExecutionId != \"\" {\n\t\t\t\tdialers := protocolstate.GetDialersWithId(opts.Options.ExecutionId)\n\t\t\t\tif dialers != nil {\n\t\t\t\t\thttpClient = dialers.DefaultHTTPClient\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch strings.ToLower(opts.Options.InputFileMode) {\n\t\t\tcase \"openapi\":\n\t\t\t\tdownloader = openapi.NewDownloader()\n\t\t\t\ttempFile, err = downloader.Download(target, opts.TempDir, httpClient)\n\t\t\tcase \"swagger\":\n\t\t\t\tdownloader = swagger.NewDownloader()\n\t\t\t\ttempFile, err = downloader.Download(target, opts.TempDir, httpClient)\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported input mode: %s\", opts.Options.InputFileMode)\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to download %s spec from url %s: %w\", opts.Options.InputFileMode, target, err)\n\t\t\t}\n\n\t\t\topts.Options.TargetsFilePath = tempFile\n\t\t}\n\t}\n\n\treturn http.NewHttpInputProvider(&http.HttpMultiFormatOptions{\n\t\tInputFile: opts.Options.TargetsFilePath,\n\t\tInputMode: opts.Options.InputFileMode,\n\t\tOptions: formats.InputFormatOptions{\n\t\t\tVariables:            generators.MergeMaps(extraVars, opts.Options.Vars.AsMap()),\n\t\t\tSkipFormatValidation: opts.Options.SkipFormatValidation,\n\t\t\tRequiredOnly:         opts.Options.FormatUseRequiredOnly,\n\t\t\tVarsTextTemplating:   opts.Options.VarsTextTemplating,","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/input/provider/interface.go#L128-L164","documentation":"Defensive default branch in provider.NewInputProvider's mode switch. Execution can only reach it when InputFileMode already case-insensitively matched \"openapi\" or \"swagger\" in the outer condition, and the lowercased switch handles exactly those two values, so in shipped code this branch is unreachable. Seeing it means a build divergence, a patched/forked binary, or a new mode was added to the outer check without a switch case.","triggerScenarios":"Running a forked or modified nuclei where the outer EqualFold condition accepts another mode string not present in the inner switch; a future regression that loosens the outer condition; in practice never triggered by stock flag values (typos fall through to the list/HTTP provider path instead).","commonSituations":"Custom internal builds adding a new input mode; SDK callers mutating Options.InputFileMode between validation and provider creation; version mismatches after cherry-picking commits.","solutions":["Confirm you are running an official build: `nuclei -version` and reinstall from the release channel","If using a fork that added a mode, add a matching case to the switch in pkg/input/provider/interface.go","SDK callers: treat this message as an assertion failure and report it upstream with the exact InputFileMode value"],"exampleFix":"// when adding a new download mode to the outer condition, extend the switch\n// before\n} else if len(opts.Options.Targets) > 0 &&\n    (strings.EqualFold(opts.Options.InputFileMode, \"openapi\") || strings.EqualFold(opts.Options.InputFileMode, \"swagger\")) {\n    switch strings.ToLower(opts.Options.InputFileMode) {\n    case \"openapi\": ...\n    case \"swagger\": ...\n    }\n\n// after\n} else if len(opts.Options.Targets) > 0 &&\n    (strings.EqualFold(opts.Options.InputFileMode, \"openapi\") || strings.EqualFold(opts.Options.InputFileMode, \"swagger\") || strings.EqualFold(opts.Options.InputFileMode, \"postman\")) {\n    switch strings.ToLower(opts.Options.InputFileMode) {\n    case \"openapi\": ...\n    case \"swagger\": ...\n    case \"postman\": ... // keep outer set and switch in sync\n    }","handlingStrategy":"validation","validationCode":"allowed := map[string]bool{\"list\": true, \"openapi\": true, \"swagger\": true}\nif !allowed[strings.ToLower(opts.Options.InputFileMode)] {\n    return fmt.Errorf(\"input mode %q is not a downloadable-spec mode; use list\", opts.Options.InputFileMode)\n}","typeGuard":"func isKnownDownloadMode(mode string) bool {\n    m := strings.ToLower(mode)\n    return m == \"openapi\" || m == \"swagger\"\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"unsupported input mode\") {\n    // stock builds cannot reach this; verify binary provenance (nuclei -version) and report upstream\n}","preventionTips":["Pin nuclei to official releases","When forking and adding input modes, keep the outer EqualFold set and the switch cases in sync","SDK callers should validate InputFileMode against a whitelist before creating the provider"],"tags":["cli","input-mode","internal","defensive-code"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}