spectreconsole/spectre.console · error · InvalidOperationException
Failed to read input in non-interactive mode.
Error message
Failed to read input in non-interactive mode.
What it means
Thrown by DefaultInput.IsKeyAvailable() when the console profile's Capabilities.Interactive is false. Spectre.Console checks the profile's interactive flag (set by terminal detection or explicit configuration) before touching System.Console.KeyAvailable. In non-interactive environments (CI, redirected stdin, headless services), reading key state is meaningless and would throw at the BCL level, so Spectre pre-empts with this InvalidOperationException.
Source
Thrown at src/Spectre.Console/Internal/DefaultInput.cs:16
namespace Spectre.Console;
internal sealed class DefaultInput : IAnsiConsoleInput
{
private readonly Profile _profile;
public DefaultInput(Profile profile)
{
_profile = profile ?? throw new ArgumentNullException(nameof(profile));
}
public bool IsKeyAvailable()
{
if (!_profile.Capabilities.Interactive)
{
throw new InvalidOperationException("Failed to read input in non-interactive mode.");
}
return System.Console.KeyAvailable;
}
public ConsoleKeyInfo? ReadKey(bool intercept)
{
if (!_profile.Capabilities.Interactive)
{
throw new InvalidOperationException("Failed to read input in non-interactive mode.");
}
return System.Console.ReadKey(intercept);
}
public async Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)
{
if (!_profile.Capabilities.Interactive)View on GitHub (pinned to 0acc92fada)
Solutions
- Guard with AnsiConsole.Profile.Capabilities.Interactive before calling input methods.
- In CI or tests, use AnsiConsole.Testing's TestConsole or mock IAnsiConsoleInput rather than real input.
- Redirect only stdout while keeping stdin as a TTY, or run in a pseudo-terminal (e.g., script, expect) for interactive tests.
- If using AnsiConsole.Create, pass a Profile with Capabilities.Interactive = true when you know a real TTY is attached.
Example fix
// before
if (AnsiConsole.Input.IsKeyAvailable()) { ... }
// after
if (AnsiConsole.Profile.Capabilities.Interactive && AnsiConsole.Input.IsKeyAvailable())
{
// safe to read keys
} Defensive patterns
Strategy: validation
Validate before calling
if (!AnsiConsole.Profile.Capabilities.Interactive)
{
throw new InvalidOperationException(
"Cannot check for key availability in a non-interactive environment.");
}
bool available = AnsiConsole.Input.IsKeyAvailable(); Type guard
static bool IsInteractiveConsole(IAnsiConsole console)
=> console.Profile.Capabilities.Interactive; Prevention
- Always check Capabilities.Interactive before calling input methods.
- Use AnsiConsole.Testing.TestConsole for automated tests.
- Run interactive tests in CI under a PTY wrapper (script, expect, ci-tty).
- Separate interactive UI code from headless-capable logic.
When it happens
Trigger: Calling AnsiConsole.Input.IsKeyAvailable() (or code that calls it, like prompt internals) when the console is running non-interactively — e.g., stdin is redirected, running under CI/build agents, or using AnsiConsole.Create with a non-interactive IAnsiConsoleOutput.
Common situations: Running Spectre.Console prompts or input-reading code in CI pipelines (GitHub Actions, Azure DevOps); unit tests that use AnsiConsole.Testing or a TestConsole without interactive capabilities; Docker/headless deployment where stdin is not a TTY; output redirected to a file or pipe.
Related errors
- Cannot show selection prompt since the current terminal isn'
- Console width must be greater than zero
- Console height must be greater than zero
- Could not convert input to a string
- At least one column must be specified.
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/8c7db6601d91d170.
Report an issue: GitHub.