spectreconsole/spectre.console · error · InvalidOperationException

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

Error message

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

What it means

Thrown by AnsiConsole.ExportText() when no Recorder is attached, i.e. AnsiConsole.Record() was never called. Exporting requires an active recorder that has been capturing writes, so exporting without one is an invalid state (InvalidOperationException).

Source

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

    /// Starts recording the console output.
    /// </summary>
    public static void Record()
    {
        if (_recorder == null)
        {
            _recorder = new Recorder(Console);
        }
    }

    /// <summary>
    /// Exports all recorded console output as text.
    /// </summary>
    /// <returns>The recorded output as text.</returns>
    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();
    }

View on GitHub (pinned to 0acc92fada)

Solutions

  1. Call AnsiConsole.Record() before any output you want to capture, then ExportText()
  2. Maintain your own flag tracking whether Record() ran, and guard the export call
  3. Wrap ExportText() in try/catch(InvalidOperationException) if recording is optional

Example fix

// before
AnsiConsole.WriteLine("hello");
var text = AnsiConsole.ExportText(); // throws

// after
AnsiConsole.Record();
AnsiConsole.WriteLine("hello");
var text = AnsiConsole.ExportText();
Defensive patterns

Strategy: try-catch

Validate before calling

// No public API exposes recording state, so track it yourself
bool recording = false;
AnsiConsole.Record();
recording = true;
AnsiConsole.WriteLine("hello");
if (recording)
    var text = AnsiConsole.ExportText();

Try / catch

try
{
    var text = AnsiConsole.ExportText();
}
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.ExportText() before AnsiConsole.Record().

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

Related errors


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