BCUninstaller/Bulk-Crap-Uninstaller · error · FormatException

Ending quotation mark is missing.

Error message

Ending quotation mark is missing.

What it means

Thrown by ProcessTools.SeparateArgsFromCommand when the command string contains an opening quotation mark (found before the first dot) but no matching closing quotation mark. pathEnd = IndexOf('"', pathEnd+1) returns -1, so the parser cannot determine where the executable path ends and raises FormatException(Localisation.Error_SeparateArgsFromCommand_MissingQuotationMark) = "Ending quotation mark is missing.".

Source

Thrown at source/KlocTools/Tools/ProcessTools.cs:181

                            return new ProcessStartCommand(fullCommand.Substring(0, rootSpace).TrimEnd(),
                                fullCommand.Substring(rootSpace));
                        }
                    }
                }
            }

            // Check if the path is contained inside of quotation marks.
            // Assume that the quotation mark must come before the dot. Otherwise, it is likely that the arguments use quotations.
            var pathEnd = fullCommand.IndexOf('"', 0, firstDot);
            if (pathEnd >= 0)
            {
                // If yes, find the closing quotation mark and set its index as path end
                pathEnd = fullCommand.IndexOf('"', pathEnd + 1);

                if (pathEnd < 0)
                {
                    // If no ending quote has been found, explode gracefully.
                    throw new FormatException(Localisation.Error_SeparateArgsFromCommand_MissingQuotationMark);
                }
                pathEnd += 1; //?
            }

            // If quotation marks were missing, check for any invalid characters after last dot
            // in case of eg: c:\test.dir thing\filename.exe?0 used to get icons
            if (pathEnd < 0)
            {
                var endIndex = 0;
                while (true)
                {
                    var dot = fullCommand.IndexOf('.', endIndex);
                    if (dot < 0)
                        break;

                    var filenameBreaker = fullCommand.IndexOfAny(SeparateArgsFromCommandInvalidChars, dot);
                    var space = fullCommand.IndexOf(' ', dot);
                    if (filenameBreaker < 0)

View on GitHub (pinned to 608321de98)

Solutions

  1. Balance the quotes in the input string before parsing (ensure an even number of '"').
  2. Normalise the command to a fully-quoted path: "C:\Path\App.exe" args.
  3. Validate quote pairing at the UI/config layer and reject or self-heal odd counts.

Example fix

// before
var c = ProcessTools.SeparateArgsFromCommand(@"""C:\My App\app.exe -x"); // missing close

// after
var c = ProcessTools.SeparateArgsFromCommand(@"""C:\My App\app.exe" -x");
Defensive patterns

Strategy: validation

Validate before calling

var quoteCount = fullCommand.Count(c => c == '"');
if (quoteCount % 2 != 0)
    throw new ArgumentException("Command has unbalanced quotes");
var cmd = ProcessTools.SeparateArgsFromCommand(fullCommand);

Type guard

static bool HasBalancedQuotes(string s) => s.Count(c => c == '"') % 2 == 0;

Try / catch

try { var c = ProcessTools.SeparateArgsFromCommand(cmd); }
catch (FormatException ex) when (ex.Message.Contains("quotation"))
{ /* prompt user to fix quoting */ }

Prevention

When it happens

Trigger: Input like "C:\Program Files\App app.exe -arg (opening quote, no close) or a command where the opening quote is actually inside arguments after the dot (the heuristic only treats a quote before the first dot as a path quote).

Common situations: Hand-edited command strings, copy-paste from browsers that drop trailing quotes, registry Run entries with malformed quoting, or shell wrapping that adds one quote.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/b578ad0556d85593. Report an issue: GitHub.