From 1dd06e73dc2d68e602885e45b1382127e663980c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 16:33:09 -0500 Subject: [PATCH] Fix stderr event loss due to missing WaitForExit in DisposeProcess (#1280) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../Client/StdioClientTransport.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs index 95f5221..191a512 100644 --- a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs +++ b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs @@ -227,6 +227,18 @@ public sealed partial class StdioClientTransport : IClientTransport // and Node.js does not kill its children when it exits properly. process.KillTree(shutdownTimeout); } + + // Ensure all redirected stderr/stdout events have been dispatched + // before disposing. Only the no-arg WaitForExit() guarantees this; + // WaitForExit(int) (as used by KillTree) does not. + // This should not hang: either the process already exited on its own + // (no child processes holding handles), or KillTree killed the entire + // process tree. If it does take too long, the test infrastructure's + // own timeout will catch it. + if (!processRunning && HasExited(process)) + { + process.WaitForExit(); + } } finally {