BCUninstaller/Bulk-Crap-Uninstaller · error · InvalidDataException

The uninstall list file could not be deserialized.

Error message

The uninstall list file could not be deserialized.

What it means

In Deserialize, after the root-element check passes, the code runs serializer.Deserialize(reader) as UninstallList and throws InvalidDataException if the result is null. A null result means the XmlSerializer returned null (which happens when the element existed but contained no deserialisable content, or the cast target mismatched), so the caller would otherwise get a NullReferenceException on result.Filters.

Source

Thrown at source/UninstallTools/Lists/UninstallList.cs:168

            if (Filters.Contains(item))
                Filters.Remove(item);
        }

        private static UninstallList Deserialize(XmlSerializer serializer, XmlReader reader)
        {
            using (reader)
            {
                reader.MoveToContent();
                if (reader.NodeType != XmlNodeType.Element ||
                    !string.Equals(reader.LocalName, nameof(UninstallList), StringComparison.Ordinal))
                {
                    throw new InvalidDataException(
                        $"The file does not contain an uninstall list. Expected root element '{nameof(UninstallList)}' but found '{reader.LocalName}'.");
                }

                var result = serializer.Deserialize(reader) as UninstallList;
                if (result == null)
                    throw new InvalidDataException("The uninstall list file could not be deserialized.");

                result.Filters ??= new List<Filter>();
                return result;
            }
        }

        private static InvalidDataException CreateInvalidDataException(Exception ex)
        {
            var xmlException = ex as XmlException ?? ex.InnerException as XmlException;
            if (xmlException != null)
            {
                return new InvalidDataException(
                    $"The uninstall list XML is invalid at line {xmlException.LineNumber}, position {xmlException.LinePosition}: {xmlException.Message}",
                    ex);
            }

            return new InvalidDataException("The uninstall list file is not valid XML.", ex);
        }

View on GitHub (pinned to 608321de98)

Solutions

  1. Keep the UninstallList type name/namespace stable, or add an XmlType/XmlRoot alias matching the legacy name.
  2. On this exception, offer to open the file as text so the user can inspect/recover it.
  3. Add an XML schema (XSD) and validate before deserialising to surface corruption earlier.

Example fix

// before
var result = serializer.Deserialize(reader) as UninstallList;

// (library code) after — keep type identity stable:
[XmlRoot("UninstallList"), XmlType("UninstallList")]
public class UninstallList { /* ... */ }

// caller side: catch and recover
try { list = UninstallList.ReadFromFile(path); }
catch (InvalidDataException) { list = RestoreFromBackup(path); }
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try { list = UninstallList.ReadFromFile(path); }
catch (InvalidDataException ex) when (ex.Message.Contains("could not be deserialized"))
{
    list = RestoreFromBackup(path) ?? new UninstallList();
}

Prevention

When it happens

Trigger: The XML has a <UninstallList> root that passed the name check but Deserialize still returned null — e.g. xsi:nil="true" on the root, a serialisation attribute mismatch between the assembly that wrote and the one that reads, or a corrupted element that the serializer silently skips.

Common situations: Version skew: the UninstallList class was refactored (renamed/namespace-changed) and an old file's root matches the local name but the type no longer maps; partial/corrupt file that deserialises to nothing.

Related errors


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