SubtitleEdit/subtitleedit · error · InvalidOperationException

Custom text output requires --custom-format=<path-to-templat

Error message

Custom text output requires --custom-format=<path-to-template.xml>.

What it means

Thrown when the target output format is 'Custom Text' / 'CustomTextFormat' but no template file was supplied via ConversionOptions.CustomFormatFile. Custom text output renders paragraphs through Nikse.SubtitleEdit's CustomTextFormatter, which requires an XML template defining the header, per-cue, and footer markup — without it there is nothing to render.

Source

Thrown at src/seconv/Core/LibSEIntegration.cs:377

        string formatName,
        string? encodingName = null,
        SubtitleFormat? sourceFormat = null,
        int? pacCodePage = null,
        string? ebuHeaderFile = null,
        ConversionOptions? options = null)
    {
        if (subtitle == null)
        {
            throw new ArgumentNullException(nameof(subtitle));
        }

        // Custom text format — render via UiLogic CustomTextFormatter
        if (formatName.Replace(" ", "").Equals("CustomTextFormat", StringComparison.OrdinalIgnoreCase) ||
            formatName.Replace(" ", "").Equals("CustomText", StringComparison.OrdinalIgnoreCase))
        {
            if (options is null || string.IsNullOrWhiteSpace(options.CustomFormatFile))
            {
                throw new InvalidOperationException("Custom text output requires --custom-format=<path-to-template.xml>.");
            }
            var template = CustomFormatTemplateLoader.Load(options.CustomFormatFile);
            var rendered = Nikse.SubtitleEdit.UiLogic.Export.CustomTextFormatter.GenerateCustomText(
                template, subtitle.Paragraphs.ToList(), Path.GetFileNameWithoutExtension(filePath), string.Empty);
            var outputDirCustom = Path.GetDirectoryName(filePath);
            if (!string.IsNullOrEmpty(outputDirCustom) && !Directory.Exists(outputDirCustom))
            {
                Directory.CreateDirectory(outputDirCustom);
            }
            File.WriteAllText(filePath, rendered, new UTF8Encoding(true));
            return;
        }

        // Plain text output — strip HTML; optional merge/unbreak and blank-line control
        if (formatName.Replace(" ", "").Equals("PlainText", StringComparison.OrdinalIgnoreCase))
        {
            var outputDirPlain = Path.GetDirectoryName(filePath);
            if (!string.IsNullOrEmpty(outputDirPlain) && !Directory.Exists(outputDirPlain))

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Pass --custom-format=<path-to-template.xml> on the CLI when the output format is Custom Text.
  2. In programmatic use, set options.CustomFormatFile to a valid template path before calling Save.
  3. If you don't have a template, export to a standard format (SRT, ASS, VTT) instead.

Example fix

// before
var options = new ConversionOptions();
LibSEIntegration.SaveSubtitle(sub, outPath, "Custom Text", options);

// after
var options = new ConversionOptions { CustomFormatFile = "my-template.xml" };
LibSEIntegration.SaveSubtitle(sub, outPath, "Custom Text", options);
Defensive patterns

Strategy: validation

Validate before calling

if (formatName.Replace(" ", "").Equals("CustomTextFormat", StringComparison.OrdinalIgnoreCase))
{
    if (options == null || string.IsNullOrWhiteSpace(options.CustomFormatFile))
        throw new InvalidOperationException("Custom text output requires a template file path.");
}

Type guard

static bool NeedsCustomTemplate(string formatName) => formatName.Replace(" ", "").Equals("CustomTextFormat", StringComparison.OrdinalIgnoreCase) || formatName.Replace(" ", "").Equals("CustomText", StringComparison.OrdinalIgnoreCase);

Try / catch

try { LibSEIntegration.SaveSubtitle(sub, outPath, "Custom Text", options); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Custom text output requires"))
{ /* prompt user to supply --custom-format=<template.xml> */ }

Prevention

When it happens

Trigger: Calling the save/export path with a formatName matching 'Custom Text' or 'CustomTextFormat' while options is null or options.CustomFormatFile is null/blank. Typically a CLI invocation where --custom-format was omitted.

Common situations: Forgetting to pass --custom-format=<template.xml> on the command line when the output format is custom text; specifying the template path with a typo so it reads as blank; programmatic use where ConversionOptions was constructed without setting CustomFormatFile.

Related errors


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