{"record":{"id":"99913775baf0912f","repo":"git-ecosystem/git-credential-manager","slug":"failed-to-open-consoleoutname-for-writing","errorCode":null,"errorMessage":"Failed to open {ConsoleOutName} for writing.","messagePattern":"Failed to open (.+?) for writing\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/Core/Interop/Windows/WindowsAnsiConsoleOutput.cs","lineNumber":55,"sourceCode":"    private readonly StreamWriter _writer;\n\n    public WindowsAnsiConsoleOutput()\n    {\n        PlatformUtils.EnsureWindows();\n\n        _handle = Kernel32.CreateFile(\n            fileName: ConsoleOutName,\n            desiredAccess: NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite,\n            shareMode: NativeFileShare.Read | NativeFileShare.Write,\n            securityAttributes: IntPtr.Zero,\n            creationDisposition: FileCreationDisposition.OpenExisting,\n            flagsAndAttributes: NativeFileAttributes.Normal,\n            templateFile: IntPtr.Zero);\n\n        if (_handle.IsInvalid)\n        {\n            _handle.Dispose();\n            throw new IOException($\"Failed to open {ConsoleOutName} for writing.\");\n        }\n\n        // Try and enable Virtual Terminal Processing\n        if (Kernel32.GetConsoleMode(_handle, out ConsoleMode mode))\n        {\n            // Ignore the return value here - older Windows versions may not support VT processing\n            // and Spectre will detect this and provide a graceful fallback experience.\n            Kernel32.SetConsoleMode(_handle, mode | ConsoleMode.EnableVirtualTerminalProcessing);\n        }\n\n        var stream = new FileStream(_handle, System.IO.FileAccess.Write);\n        _writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))\n        {\n            AutoFlush = true,\n        };\n    }\n\n    public TextWriter Writer => _writer;","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Interop/Windows/WindowsAnsiConsoleOutput.cs#L37-L73","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run git from a real console session so CONOUT$ is available.","Use non-interactive configuration (GCM_INTERACTIVE=never, credential.credentialStore=wincredman) so the helper never needs to render console prompts.","For headless automation, pre-authenticate interactively once and reuse cached credentials.","Ensure the launching process isn't closing or replacing the child's standard output handles."],"exampleFix":"// before (Windows service spawning git interactively)\n// IOException: failed to open CONOUT$\n// after\nvar psi = new ProcessStartInfo(\"git\", \"push\") { UseShellExecute = false, CreateNoWindow = true };\n// plus non-interactive config: credential.credentialStore=wincredman","handlingStrategy":"try-catch","validationCode":"bool HasConsoleOut() => Kernel32.GetConsoleWindow() != IntPtr.Zero;","typeGuard":"static bool HasUsableConsole() =>\n    Kernel32.GetConsoleWindow() != IntPtr.Zero &&\n    Kernel32.GetConsoleMode(Kernel32.GetStdHandle(-11), out _);","tryCatchPattern":"try { using var output = new WindowsAnsiConsoleOutput(); ... }\ncatch (IOException)\n{ // no console attached: suppress interactive output / use non-interactive auth\n  return RunHeadlessFallback(); }","preventionTips":["Ensure services/scheduled tasks that call git never need interactive prompts.","Configure GCM_INTERACTIVE=never and wincredman store for unattended runs.","Don't close or replace the child process's stdout handles before helper output.","Pre-authenticate once in an interactive session, then reuse cached credentials."],"tags":["windows","console","io","terminal"],"backgroundTag":"file-open-failed","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}