{"record":{"id":"3effe0d67bbaa378","repo":"github/copilot-sdk","slug":"cli-process-exited-unexpectedly-stderr-stderrou","errorCode":null,"errorMessage":"CLI process exited unexpectedly.\nstderr: {stderrOutput}","messagePattern":"CLI process exited unexpectedly\\.\nstderr: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Client.cs","lineNumber":515,"sourceCode":"\n                if (connection is not null)\n                {\n                    await CleanupConnectionAsync(connection, errors: null, gracefulRuntimeShutdown: false);\n                }\n                else if (cliProcess is not null)\n                {\n                    await CleanupCliProcessAsync(cliProcess, stderrPump, errors: null, _logger);\n                }\n\n                if (ex is IOException\n                    && cliProcess is not null\n                    && stderrPump is not null\n                    && !ex.Message.Contains(\"stderr:\", StringComparison.OrdinalIgnoreCase))\n                {\n                    var stderrOutput = GetStderrOutput(stderrPump.Buffer);\n                    if (!string.IsNullOrEmpty(stderrOutput))\n                    {\n                        throw new IOException(\n                            FormatCliExitedMessage(\"CLI process exited unexpectedly.\", stderrOutput),\n                            ex);\n                    }\n                }\n\n                throw;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Disconnects from the Copilot server and closes all active sessions.\n    /// </summary>\n    /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n    /// <remarks>\n    /// <para>\n    /// This method performs graceful cleanup:\n    /// <list type=\"number\">","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/Client.cs#L497-L533","documentation":"StartAsync wraps an unexpected CLI process exit in an IOException that appends the collected stderr output. When the child CLI process dies during startup or operation and its stderr contains diagnostics, the library rethrows as 'CLI process exited unexpectedly.\\nstderr: ...' with the original exception as the inner exception, so the underlying failure reason is preserved in the stderr text.","triggerScenarios":"Calling StartAsync/EnsureConnectedAsync (or any operation over an active session) when the spawned CLI process crashes or exits early; the stderr pump buffer is non-empty and the exception is not already a stderr-formatted message.","commonSituations":"Unsupported or corrupt CLI installation; missing runtime dependencies for the CLI binary; port conflicts or startup crashes printed to stderr; the CLI being killed by the OS; version mismatch between SDK and CLI.","solutions":["Read the 'stderr:' section of the message - it contains the actual crash reason from the CLI.","Verify the CLI is installed, executable, and a version compatible with the SDK.","Run the CLI manually with the same arguments to reproduce and inspect the failure.","Retry via EnsureConnectedAsync after fixing the underlying cause; check innerException for the original exit details."],"exampleFix":"// before\nvar client = new CopilotClient(options, RuntimeConnection.ForStdio()); // old CLI version crashes on startup\n// after\n// 1. inspect stderr in the IOException message\ntry { await client.StartAsync(); }\ncatch (IOException ex) { Console.WriteLine(ex.Message); } // shows CLI stderr\n// 2. update the CLI to a compatible version, then retry","handlingStrategy":"try-catch","validationCode":"// verify the CLI runs before connecting:\nvar psi = new ProcessStartInfo(cliPath, \"--version\") { RedirectStandardError = true };\nusing var p = Process.Start(psi);\nif (p is null || p.WaitForExit(5000) && p.ExitCode != 0)\n    throw new InvalidOperationException(\"CLI is not healthy before start.\");","typeGuard":"null","tryCatchPattern":"try { await client.StartAsync(); }\ncatch (IOException ex) when (ex.Message.StartsWith(\"CLI process exited unexpectedly\"))\n{\n    var stderr = ex.Message[(ex.Message.IndexOf(\"stderr:\") + 7)..];\n    logger.LogError(ex, \"CLI crashed. stderr: {Stderr}\", stderr);\n}","preventionTips":["Pin a CLI version compatible with the SDK","Check CLI installation and dependencies in environment setup","Capture and log stderr on every startup failure","Add a health-check step that runs 'cli --version' before connecting"],"tags":["dotnet","process","cli","crash","stderr"],"backgroundTag":"process-exited-unexpectedly","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}