{"record":{"id":"c25d105af6473b5e","repo":"microsoft/aspire","slug":"failed-to-invoke-waitforsingleobject-while-starting-tracked","errorCode":null,"errorMessage":"Failed to invoke WaitForSingleObject while starting tracked browser CDP pipe.","messagePattern":"Failed to invoke WaitForSingleObject while starting tracked browser CDP pipe\\.","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Browsers/BrowserLogsPipeBrowserProcessLauncher.Windows.cs","lineNumber":222,"sourceCode":"                builder.Append('\\\\');\n                builder.Append('\"');\n                continue;\n            }\n\n            builder.Append(character);\n        }\n\n        builder.Append('\"');\n    }\n\n    private static async Task<BrowserLogsProcessResult> WaitForWindowsProcessAsync(SafeWaitHandle processHandle)\n    {\n        return await Task.Run(() =>\n        {\n            var waitResult = WaitForSingleObject(processHandle.DangerousGetHandle(), INFINITE);\n            if (waitResult != WAIT_OBJECT_0)\n            {\n                throw CreateWindowsException(\"WaitForSingleObject\");\n            }\n\n            if (!GetExitCodeProcess(processHandle.DangerousGetHandle(), out var exitCode))\n            {\n                throw CreateWindowsException(\"GetExitCodeProcess\");\n            }\n\n            return new BrowserLogsProcessResult(unchecked((int)exitCode));\n        }).ConfigureAwait(false);\n    }\n\n    private static Win32Exception CreateWindowsException(string operation) =>\n        new(Marshal.GetLastWin32Error(), $\"Failed to invoke {operation} while starting tracked browser CDP pipe.\");\n\n    private static void CloseWindowsHandle(IntPtr handle)\n    {\n        if (handle != IntPtr.Zero && !CloseHandle(handle))\n        {","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Browsers/BrowserLogsPipeBrowserProcessLauncher.Windows.cs#L204-L240","documentation":"The launcher waits for the tracked browser process to exit using WaitForSingleObject(INFINITE). If the wait returns anything other than WAIT_OBJECT_0 (e.g. WAIT_FAILED), the launcher throws this Win32Exception-named error. It means the OS-level wait on the process handle failed rather than the process exiting with a bad exit code.","triggerScenarios":"WaitForWindowsProcessAsync's Task.Run body calls WaitForSingleObject(processHandle.DangerousGetHandle(), INFINITE) and gets a result other than WAIT_OBJECT_0 - usually WAIT_FAILED because the handle was invalid, closed, or already destroyed.","commonSituations":"Browser process terminated and handle became invalid concurrently; a stale or disposed handle passed in; rare OS failures under handle pressure; external watchdog or antivirus force-killing the browser mid-session.","solutions":["Check the inner NativeErrorCode (WAIT_FAILED usually means an invalid handle).","Ensure no other code closes or disposes the browser process handle while the wait is pending.","Retry the launch - usually transient; the tracked browser session will be re-created.","Verify the browser isn't being force-killed by an external watchdog or antivirus.","Update Aspire.Hosting.Browsers in case of known handle-lifecycle fixes."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before waiting, confirm the process handle is alive\nif (processHandle.IsClosed || processHandle.IsInvalid)\n    throw new InvalidOperationException(\"Browser process handle is no longer valid; relaunch required.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var result = await WaitForBrowserAsync(processHandle);\n}\ncatch (Win32Exception ex) when (ex.Message.Contains(\"WaitForSingleObject\"))\n{\n    logger.LogWarning(ex, \"Browser wait failed (Win32 {Code}); relaunching session.\", ex.NativeErrorCode);\n    await RelaunchTrackedBrowserAsync();\n}","preventionTips":["Never dispose or close the browser process handle while a wait is pending.","Avoid external watchdogs that force-kill the browser during tracked sessions.","Treat wait failures as transient and relaunch the session."],"tags":["windows","process-wait","win32","browser"],"backgroundTag":"process-wait-failed","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}