SubtitleEdit/subtitleedit · error · InvalidDataException

Failed to parse custom-format XML at {xmlPath}: {ex.Message}

Error message

Failed to parse custom-format XML at {xmlPath}: {ex.Message}

What it means

Thrown when deserialising the custom-format XML raised an exception other than FileNotFoundException/InvalidDataException (XmlException, InvalidOperationException from the serializer, IOException, etc.). The loader catches it and re-throws as InvalidDataException preserving the original as InnerException, so callers get one exception type for all malformed-template cases.

Source

Thrown at src/seconv/Core/CustomFormatTemplateLoader.cs:53

            using var fs = File.OpenRead(xmlPath);
            var serializer = new XmlSerializer(typeof(XmlShape));
            var shape = (XmlShape?)serializer.Deserialize(fs)
                ?? throw new InvalidDataException($"Custom format template is empty: {xmlPath}");

            return new CustomFormatTemplate
            {
                Name = shape.Name,
                Extension = shape.Extension,
                FormatHeader = shape.FormatHeader,
                FormatParagraph = shape.FormatParagraph,
                FormatFooter = shape.FormatFooter,
                FormatTimeCode = shape.FormatTimeCode,
                FormatNewLine = shape.FormatNewLine,
            };
        }
        catch (Exception ex) when (ex is not FileNotFoundException && ex is not InvalidDataException)
        {
            throw new InvalidDataException($"Failed to parse custom-format XML at {xmlPath}: {ex.Message}", ex);
        }
    }
}

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Validate the XML well-formedness in an editor or xmllint.
  2. Inspect InnerException for the exact line/reason reported by XmlSerializer.
  3. Ensure the file is UTF-8 (with or without BOM) and matches the XmlShape schema (root <CustomFormatItem>).
  4. Regenerate the template from a known-good export and diff against the broken one.

Example fix

// before
var tpl = CustomFormatTemplateLoader.Load(path);

// after
CustomFormatTemplate tpl;
try { tpl = CustomFormatTemplateLoader.Load(path); }
catch (InvalidDataException ex) { Console.Error.WriteLine($"Bad template: {ex.Message} (root: {ex.InnerException?.Message})"); return; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate XML well-formedness before delegating to the loader.
try { var doc = XDocument.Load(xmlPath); }  // throws XmlException if malformed
catch (XmlException) { return Error($"Malformed XML: {xmlPath}"); }

Try / catch

try { tpl = CustomFormatTemplateLoader.Load(xmlPath); }
catch (InvalidDataException ex) { Console.Error.WriteLine($"Bad template: {ex.Message} (root: {ex.InnerException?.Message})"); return; }

Prevention

When it happens

Trigger: Calling Load on an XML that is not well-formed (unbalanced tags, bad encoding, invalid characters) or whose structure violates the XmlShape contract — the catch at line 51 wraps the serializer's XmlException/InvalidOperationException into InvalidDataException at line 53.

Common situations: Hand-edited XML with a typo (unclosed tag, stray &); a template saved in the wrong encoding (BOM/UTF-16); an XML containing characters illegal in the target element types; a template copied from a newer/different schema.

Understand the failure class

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/3f5f5dc2dd503373. Report an issue: GitHub.