SubtitleEdit/subtitleedit · error · InvalidDataException

Custom format template is empty: {xmlPath}

Error message

Custom format template is empty: {xmlPath}

What it means

Thrown when XmlSerializer.Deserialize returns null for the custom-format template — the file exists and opened for reading but deserialised to no object. This indicates an XML document that is structurally empty or whose root does not map to the XmlShape ('CustomFormatItem' root). Treated as corrupt/empty input.

Source

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

        public string FormatParagraph { get; set; } = string.Empty;
        public string FormatFooter { get; set; } = string.Empty;
        public string FormatTimeCode { get; set; } = string.Empty;
        public string? FormatNewLine { get; set; }
    }

    public static CustomFormatTemplate Load(string xmlPath)
    {
        if (!File.Exists(xmlPath))
        {
            throw new FileNotFoundException($"Custom format template not found: {xmlPath}", xmlPath);
        }

        try
        {
            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. Open the XML and confirm it has a <CustomFormatItem> root with the expected child elements (Name, Extension, FormatHeader, FormatParagraph, FormatFooter, FormatTimeCode).
  2. If the file is empty, regenerate it from a working custom-format export.
  3. Provide a minimal valid template body and re-save.

Example fix

<!-- before: empty file -->

<!-- after: minimal valid template -->
<CustomFormatItem>
  <Name>MyFormat</Name>
  <Extension>.txt</Extension>
  <FormatHeader></FormatHeader>
  <FormatParagraph>{start} {text}</FormatParagraph>
  <FormatFooter></FormatFooter>
  <FormatTimeCode>HH:mm:ss,fff</FormatTimeCode>
</CustomFormatItem>
Defensive patterns

Strategy: validation

Validate before calling

// Reject empty/whitespace-only files before deserialising.
var info = new FileInfo(xmlPath);
if (info.Length == 0 || string.IsNullOrWhiteSpace(File.ReadAllText(xmlPath)))
    return Error($"Custom format template is empty: {xmlPath}");

Try / catch

try { tpl = CustomFormatTemplateLoader.Load(xmlPath); }
catch (InvalidDataException ex) when (ex.Message.Contains("is empty"))
{ Console.Error.WriteLine(ex.Message); return; }

Prevention

When it happens

Trigger: Calling Load on an existing but empty file, or an XML whose content the XmlSerializer maps to null (e.g. an effectively empty <CustomFormatItem/> that yields a null cast at line 37-38). Distinct from a parse error (error 97) which is a thrown exception.

Common situations: A zero-byte or whitespace-only .xml file; an XML with a different root element that the serializer silently skips; a template exported incorrectly by another tool producing an empty document.

Related errors


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