From e6db415940a3aabb6d00a1cff445d25213eedf9e Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:42:16 +0200 Subject: [PATCH] Fix race condition in StdioClientTransport on .NET Framework (#996) 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 | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs index f3e6241..55483b6 100644 --- a/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs +++ b/src/ModelContextProtocol.Core/Client/StdioClientTransport.cs @@ -25,6 +25,12 @@ namespace ModelContextProtocol.Client; /// public sealed partial class StdioClientTransport : IClientTransport { +#if !NET + // On .NET Framework, we need to synchronize access to Console.InputEncoding + // to prevent race conditions when multiple transports are created concurrently. + private static readonly object s_consoleEncodingLock = new(); +#endif + private readonly StdioClientTransportOptions _options; private readonly ILoggerFactory? _loggerFactory; @@ -159,15 +165,20 @@ public sealed partial class StdioClientTransport : IClientTransport #if NET processStarted = process.Start(); #else - Encoding originalInputEncoding = Console.InputEncoding; - try + // IMPORTANT: This must be synchronized to prevent race conditions when multiple + // transports are created concurrently. + lock (s_consoleEncodingLock) { - Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding; - processStarted = process.Start(); - } - finally - { - Console.InputEncoding = originalInputEncoding; + Encoding originalInputEncoding = Console.InputEncoding; + try + { + Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding; + processStarted = process.Start(); + } + finally + { + Console.InputEncoding = originalInputEncoding; + } } #endif