From 88a483609b70eb1d59fd2cd38ef422013e7f5e6d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 5 Jul 2026 17:16:10 +0000 Subject: [PATCH] fix(cli): guard against a renderer returning no documents WriteOutput accessed documents[0] without checking the list was non-empty. The IErrorDocumentationRenderer.Render contract promises at least one document, but a custom renderer can violate it, in which case documents[0] threw an opaque ArgumentOutOfRangeException. Add a guard that fails with a clear message naming the offending renderer format before any documents[0] access. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RZShkZnouh6f1yy6YGaFwx --- FirstClassErrors.Cli/GenerateCommand.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/FirstClassErrors.Cli/GenerateCommand.cs b/FirstClassErrors.Cli/GenerateCommand.cs index 884a804..d370701 100644 --- a/FirstClassErrors.Cli/GenerateCommand.cs +++ b/FirstClassErrors.Cli/GenerateCommand.cs @@ -99,7 +99,7 @@ protected override int Execute(CommandContext context, GenerateSettings settings RenderRequest request = new(layout, culture); IReadOnlyList documents = renderer.Render(catalog, request); - WriteOutput(documents, output, logger); + WriteOutput(documents, renderer.Format, output, logger); return 0; } catch (Exception exception) { @@ -133,7 +133,13 @@ private static CultureInfo ResolveCulture(string language) { } } - private static void WriteOutput(IReadOnlyList documents, string? outputPath, ConsoleGenerationLogger logger) { + private static void WriteOutput(IReadOnlyList documents, string format, string? outputPath, ConsoleGenerationLogger logger) { + // A renderer must honour its contract of returning at least one document. If a (custom) renderer returns an + // empty list, fail with a clear message rather than an opaque IndexOutOfRange from documents[0] below. + if (documents.Count == 0) { + throw new InvalidOperationException($"The '{format}' renderer produced no documents; a renderer must return at least one document."); + } + bool hasOutput = string.IsNullOrWhiteSpace(outputPath) is false; // No target: only a single document can go to standard output.