{"record":{"id":"870c104b8ca0b0b8","repo":"BCUninstaller/Bulk-Crap-Uninstaller","slug":"file-name-must-contain-an-extension-separated-by-a","errorCode":null,"errorMessage":"File name must contain an extension separated by a dot.\n{fullCommand}","messagePattern":"File name must contain an extension separated by a dot\\.\n(.+?)","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"source/KlocTools/Tools/ProcessTools.cs","lineNumber":279,"sourceCode":"            var pathRootEnd = pathRoot < 0 ? 0 : pathRoot + 2;\n\n            var breakChars = SeparateArgsFromCommandInvalidChars.Except(new[] { '\\\\' }).ToArray();\n\n            // Check if there are any invalid path chars before the start we found. If yes, our path is most likely an argument.\n            if (pathRootEnd > 0 && fullCommand.IndexOfAny(breakChars, 0, pathRootEnd - 2) >= 0)\n                pathRootEnd = 0;\n            var breakIndex = fullCommand.IndexOfAny(breakChars, pathRootEnd);\n\n            // If there are no invalid path chars, it's probably just a naked filename or directory path.\n            if (breakIndex < 0)\n                return new ProcessStartCommand(fullCommand.Trim('\"'));\n\n            // The invalid char has to have at least 1 space before it to count as an argument. Otherwise the input is likely garbage.\n            if (breakIndex > 0 && fullCommand[breakIndex - 1] == ' ')\n                return new ProcessStartCommand(fullCommand.Substring(0, breakIndex - 1).TrimEnd(),\n                    fullCommand.Substring(breakIndex));\n\n            throw new FormatException(Localisation.Error_SeparateArgsFromCommand_NoDot + \"\\n\" + fullCommand);\n        }\n\n        /// <summary>\n        ///     Change default culture info for new threads\n        /// </summary>\n        /// <param name=\"culture\"></param>\n        public static void SetDefaultCulture(CultureInfo culture)\n        {\n            var type = typeof(CultureInfo);\n\n            if (Environment.Version.Major < 4)\n            {\n                // Fields used before .Net 4.0\n                try\n                {\n                    type.InvokeMember(\"m_userDefaultCulture\",\n                        BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,\n                        null,","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/BCUninstaller/Bulk-Crap-Uninstaller/blob/608321de98e92297377b1eb69029af55c25504a1/source/KlocTools/Tools/ProcessTools.cs#L261-L297","documentation":"Thrown in the no-dot branch of SeparateArgsFromCommand (SeparateNonDottedCommand). When breakChars are found in the input (so it looks like command + args) but the break index is at position 0 or is not preceded by a space, the parser cannot split a filename from arguments and throws FormatException(Localisation.Error_SeparateArgsFromCommand_NoDot + \"\\n\" + fullCommand) — message: \"File name must contain an extension separated by a dot.\". The parser expects an executable path with a dotted extension.","triggerScenarios":"Passing a command whose executable has no file extension (no dot) yet contains argument-separator characters, e.g. \"myapp -flag\" where 'myapp' has no '.exe', or input beginning with an invalid path char so breakIndex==0.","commonSituations":"Unix-style or script commands without extensions, bare executable names on PATH passed verbatim, or arguments glued to the filename without a separating space.","solutions":["Ensure the executable portion includes its extension (append \".exe\" if appropriate) before parsing.","Insert a space between the executable and its arguments so breakIndex is preceded by ' '.","If the input is intentionally extension-less, skip SeparateArgsFromCommand and treat the whole token as the command."],"exampleFix":"// before\nvar c = ProcessTools.SeparateArgsFromCommand(\"myapp-x arg\"); // no dot, leading break char\n\n// after\nvar c = ProcessTools.SeparateArgsFromCommand(\"myapp-x.exe arg\");","handlingStrategy":"validation","validationCode":"if (fullCommand.IndexOf('.') < 0)\n    throw new ArgumentException(\"Executable must include a dotted extension\");\nvar cmd = ProcessTools.SeparateArgsFromCommand(fullCommand);","typeGuard":"static bool HasDottedExtension(string cmd) => cmd != null && cmd.Contains('.');","tryCatchPattern":"try { var c = ProcessTools.SeparateArgsFromCommand(cmd); }\ncatch (FormatException ex) when (ex.Message.Contains(\"extension separated by a dot\"))\n{ /* append .exe or treat as bare command */ }","preventionTips":["Always include the executable extension (.exe) in command strings.","Separate the executable from arguments with a space.","Route intentionally extension-less commands around this parser."],"tags":["parsing","command-line","validation","csharp","kloctools"],"backgroundTag":null,"analyzedSha":"608321de98e92297377b1eb69029af55c25504a1","analyzedAt":"2026-08-13T12:17:35.389Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}