{"record":{"id":"d0bd8758fe7fb9fa","repo":"SubtitleEdit/subtitleedit","slug":"no-paragraphs-to-render","errorCode":null,"errorMessage":"No paragraphs to render.","messagePattern":"No paragraphs to render\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/ImageOutputWriter.cs","lineNumber":56,"sourceCode":"                => new ExportHandlerDCinemaSmpte2014Png(),\n            var x when x.Equals(\"Images with time codes in file name\", StringComparison.OrdinalIgnoreCase) || x.Equals(\"ImagesWithTimeCodes\", StringComparison.OrdinalIgnoreCase)\n                => new ExportHandlerImagesWithTimeCode(),\n            // WebVTT thumbnail bundle: a directory of numbered PNG sprites plus an\n            // index.vtt that references each by start/end time. The handler treats\n            // the output path as a folder (creates it, writes PNGs + index.vtt\n            // inside), so e.g. `seconv movie.srt webvttthumbnail` produces\n            // `movie.vtt/0001.png`, `0002.png`, ..., `index.vtt`.\n            var x when x.Equals(\"WebVTT Thumbnail\", StringComparison.OrdinalIgnoreCase) || x.Equals(\"WebVttThumbnail\", StringComparison.OrdinalIgnoreCase)\n                => new ExportHandlerWebVttThumbnail(),\n            _ => null,\n        };\n    }\n\n    public static void Write(Subtitle subtitle, string filePath, IExportHandler handler, ConversionOptions options)\n    {\n        if (subtitle.Paragraphs.Count == 0)\n        {\n            throw new InvalidOperationException(\"No paragraphs to render.\");\n        }\n\n        var (screenWidth, screenHeight) = options.Resolution ?? (1920, 1080);\n\n        // \"{\\pos(x,y)}\" is in the script's own resolution, the export canvas may be another one.\n        var (scriptWidth, scriptHeight) = ExportTextTags.GetScriptResolution(subtitle.Header);\n\n        // Pre-render header with the first paragraph as a representative\n        var firstParam = BuildParameter(subtitle.Paragraphs[0], 0, screenWidth, screenHeight, options);\n        firstParam.Bitmap = ImageRenderer.GenerateBitmap(firstParam);\n        handler.WriteHeader(filePath, firstParam);\n        firstParam.Bitmap?.Dispose();\n\n        for (var i = 0; i < subtitle.Paragraphs.Count; i++)\n        {\n            var p = subtitle.Paragraphs[i];\n            var ip = BuildParameter(p, i, screenWidth, screenHeight, options);\n            ip.Bitmap = ImageRenderer.GenerateBitmap(ip);","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/ImageOutputWriter.cs#L38-L74","documentation":"Thrown by ImageOutputWriter.Write when the subtitle being exported to an image-based format (BDN-XML, Blu-ray sup, DOST, WebVTT thumbnail, etc.) has zero paragraphs (cues). Image rendering iterates over Paragraphs to generate bitmaps — an empty subtitle produces no images and no index, so the writer refuses rather than emit a hollow export.","triggerScenarios":"Calling ImageOutputWriter.Write(subtitle, filePath, handler, options) where subtitle.Paragraphs.Count == 0. This happens when the loaded source subtitle is empty, when all paragraphs were filtered out upstream (e.g. by a timing or style filter), or when a malformed source produced no decodable cues despite loading without error.","commonSituations":"Converting a nearly-empty or whitespace-only SRT/ASS to an image format; a source file whose paragraphs were all removed by a sync/split/cleanup pass before the image export step; piping a subtitle through an intermediate filter that stripped every cue.","solutions":["Check subtitle.Paragraphs.Count > 0 before invoking the image export path, and report a meaningful message to the end user.","Inspect the source file — if it should have cues, the load or an upstream filter is silently dropping them; enable warnings and verify paragraph count right after LoadSubtitleWithFormat returns.","If the empty subtitle is expected (e.g. a template), skip the image export entirely rather than calling Write."],"exampleFix":"// before\nImageOutputWriter.Write(subtitle, outPath, handler, options);\n\n// after\nif (subtitle.Paragraphs.Count == 0)\n    return; // or report \"no subtitles to render\"\nImageOutputWriter.Write(subtitle, outPath, handler, options);","handlingStrategy":"validation","validationCode":"if (subtitle == null || subtitle.Paragraphs.Count == 0)\n{\n    Console.Error.WriteLine(\"No subtitle paragraphs to render to image format.\");\n    return;\n}","typeGuard":"static bool HasRenderableParagraphs(Subtitle subtitle) => subtitle != null && subtitle.Paragraphs.Count > 0;","tryCatchPattern":"try { ImageOutputWriter.Write(subtitle, outPath, handler, options); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"No paragraphs to render\"))\n{ /* report empty-input error to user */ }","preventionTips":["Always check subtitle.Paragraphs.Count immediately after loading, especially before branching to image export.","Log a warning when a loaded subtitle has zero paragraphs — it usually indicates a silent parse or filter failure.","Gate the image export path behind a non-empty-paragraph precondition in your conversion pipeline."],"tags":["image-export","empty-input","validation","subtitles"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}