{"record":{"id":"8c7db6601d91d170","repo":"spectreconsole/spectre.console","slug":"failed-to-read-input-in-non-interactive-mode","errorCode":null,"errorMessage":"Failed to read input in non-interactive mode.","messagePattern":"Failed to read input in non-interactive mode\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Spectre.Console/Internal/DefaultInput.cs","lineNumber":16,"sourceCode":"namespace Spectre.Console;\n\ninternal sealed class DefaultInput : IAnsiConsoleInput\n{\n    private readonly Profile _profile;\n\n    public DefaultInput(Profile profile)\n    {\n        _profile = profile ?? throw new ArgumentNullException(nameof(profile));\n    }\n\n    public bool IsKeyAvailable()\n    {\n        if (!_profile.Capabilities.Interactive)\n        {\n            throw new InvalidOperationException(\"Failed to read input in non-interactive mode.\");\n        }\n\n        return System.Console.KeyAvailable;\n    }\n\n    public ConsoleKeyInfo? ReadKey(bool intercept)\n    {\n        if (!_profile.Capabilities.Interactive)\n        {\n            throw new InvalidOperationException(\"Failed to read input in non-interactive mode.\");\n        }\n\n        return System.Console.ReadKey(intercept);\n    }\n\n    public async Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)\n    {\n        if (!_profile.Capabilities.Interactive)","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/spectreconsole/spectre.console/blob/0acc92fada6c42f13984e79c2b5f3d993bdfb099/src/Spectre.Console/Internal/DefaultInput.cs#L1-L34","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif (AnsiConsole.Input.IsKeyAvailable()) { ... }\n\n// after\nif (AnsiConsole.Profile.Capabilities.Interactive && AnsiConsole.Input.IsKeyAvailable())\n{\n    // safe to read keys\n}","handlingStrategy":"validation","validationCode":"if (!AnsiConsole.Profile.Capabilities.Interactive)\n{\n    throw new InvalidOperationException(\n        \"Cannot check for key availability in a non-interactive environment.\");\n}\nbool available = AnsiConsole.Input.IsKeyAvailable();","typeGuard":"static bool IsInteractiveConsole(IAnsiConsole console)\n    => console.Profile.Capabilities.Interactive;","tryCatchPattern":null,"preventionTips":["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."],"tags":["invalidoperationexception","input","non-interactive","terminal","ci"],"backgroundTag":null,"analyzedSha":"0acc92fada6c42f13984e79c2b5f3d993bdfb099","analyzedAt":"2026-08-13T18:27:21.983Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}