spectreconsole/spectre.console · error · InvalidOperationException

Cannot export HTML since a recording hasn't been started.

Error message

Cannot export HTML since a recording hasn't been started.

What it means

Thrown by AnsiConsole.ExportHtml() when no Recorder is attached, i.e. AnsiConsole.Record() was never called. The HTML exporter needs captured console writes, so exporting without recording is an invalid state (InvalidOperationException).

Source

Thrown at src/Spectre.Console/AnsiConsole.Recording.cs:41

    public static string ExportText()
    {
        if (_recorder == null)
        {
            throw new InvalidOperationException("Cannot export text since a recording hasn't been started.");
        }

        return _recorder.ExportText();
    }

    /// <summary>
    /// Exports all recorded console output as HTML text.
    /// </summary>
    /// <returns>The recorded output as HTML text.</returns>
    public static string ExportHtml()
    {
        if (_recorder == null)
        {
            throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
        }

        return _recorder.ExportHtml();
    }

    /// <summary>
    /// Exports all recorded console output using a custom encoder.
    /// </summary>
    /// <param name="encoder">The encoder to use.</param>
    /// <returns>The recorded output.</returns>
    public static string ExportCustom(IAnsiConsoleEncoder encoder)
    {
        if (_recorder == null)
        {
            throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
        }

        ArgumentNullException.ThrowIfNull(encoder);

View on GitHub (pinned to 0acc92fada)

Solutions

  1. Call AnsiConsole.Record() before the output you want captured, then ExportHtml()
  2. Track recording state yourself and guard the export call
  3. Wrap ExportHtml() in try/catch(InvalidOperationException) if recording is optional

Example fix

// before
AnsiConsole.WriteLine("hello");
var html = AnsiConsole.ExportHtml(); // throws

// after
AnsiConsole.Record();
AnsiConsole.WriteLine("hello");
var html = AnsiConsole.ExportHtml();
Defensive patterns

Strategy: try-catch

Validate before calling

// No public API exposes recording state; track it locally
bool recording = false;
AnsiConsole.Record();
recording = true;
AnsiConsole.WriteLine("hello");
if (recording)
    var html = AnsiConsole.ExportHtml();

Try / catch

try
{
    var html = AnsiConsole.ExportHtml();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("recording hasn't been started"))
{
    // recording was never started; handle gracefully
}

Prevention

When it happens

Trigger: Calling AnsiConsole.ExportHtml() before AnsiConsole.Record().

Common situations: Forgot to call Record(); a code path exports HTML in a branch where recording never started; reordered setup after a refactor; test asserting HTML export without setup.

Related errors


AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13). Data as JSON: /api/errors/a87530e3919f4c2a. Report an issue: GitHub.