git-ecosystem/git-credential-manager · error · IOException

Failed to open for writing.

Error message

Failed to open {ConsoleOutName} for writing.

What it means

WindowsAnsiConsoleOutput's constructor opens the console output device (CONOUT$) via CreateFile to render ANSI output. If the handle is invalid it disposes and throws IOException. Afterwards it attempts to enable Virtual Terminal Processing, but that step is best-effort and does not throw.

Solutions

  1. Run git from a real console session so CONOUT$ is available.
  2. Use non-interactive configuration (GCM_INTERACTIVE=never, credential.credentialStore=wincredman) so the helper never needs to render console prompts.
  3. For headless automation, pre-authenticate interactively once and reuse cached credentials.
  4. Ensure the launching process isn't closing or replacing the child's standard output handles.

Example fix

// before (Windows service spawning git interactively)
// IOException: failed to open CONOUT$
// after
var psi = new ProcessStartInfo("git", "push") { UseShellExecute = false, CreateNoWindow = true };
// plus non-interactive config: credential.credentialStore=wincredman
Defensive patterns

Strategy: try-catch

Validate before calling

bool HasConsoleOut() => Kernel32.GetConsoleWindow() != IntPtr.Zero;

Type guard

static bool HasUsableConsole() =>
    Kernel32.GetConsoleWindow() != IntPtr.Zero &&
    Kernel32.GetConsoleMode(Kernel32.GetStdHandle(-11), out _);

Try / catch

try { using var output = new WindowsAnsiConsoleOutput(); ... }
catch (IOException)
{ // no console attached: suppress interactive output / use non-interactive auth
  return RunHeadlessFallback(); }

Prevention

When it happens

Trigger: Creating WindowsAnsiConsoleOutput when CreateFile on CONOUT$ fails: process has no attached console (GUI app, service, scheduled task) or output handle was closed/redirected away from a console.

Common situations: git invoked from a GUI launcher or Windows service with no console; scheduled tasks running when no user session exists; output redirected with no console allocated; restricted environments where console objects are unavailable.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/99913775baf0912f. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/Interop/Windows/WindowsAnsiConsoleOutput.cs:55

    private readonly StreamWriter _writer;

    public WindowsAnsiConsoleOutput()
    {
        PlatformUtils.EnsureWindows();

        _handle = Kernel32.CreateFile(
            fileName: ConsoleOutName,
            desiredAccess: NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite,
            shareMode: NativeFileShare.Read | NativeFileShare.Write,
            securityAttributes: IntPtr.Zero,
            creationDisposition: FileCreationDisposition.OpenExisting,
            flagsAndAttributes: NativeFileAttributes.Normal,
            templateFile: IntPtr.Zero);

        if (_handle.IsInvalid)
        {
            _handle.Dispose();
            throw new IOException($"Failed to open {ConsoleOutName} for writing.");
        }

        // Try and enable Virtual Terminal Processing
        if (Kernel32.GetConsoleMode(_handle, out ConsoleMode mode))
        {
            // Ignore the return value here - older Windows versions may not support VT processing
            // and Spectre will detect this and provide a graceful fallback experience.
            Kernel32.SetConsoleMode(_handle, mode | ConsoleMode.EnableVirtualTerminalProcessing);
        }

        var stream = new FileStream(_handle, System.IO.FileAccess.Write);
        _writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))
        {
            AutoFlush = true,
        };
    }

    public TextWriter Writer => _writer;

View on GitHub (pinned to e8ce762cd0)