{"record":{"id":"1c4d681371648c79","repo":"microsoft/aspire","slug":"failed-to-invoke-closehandle-while-starting-tracked-browser","errorCode":null,"errorMessage":"Failed to invoke CloseHandle while starting tracked browser CDP pipe.","messagePattern":"Failed to invoke CloseHandle while starting tracked browser CDP pipe\\.","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Browsers/BrowserLogsPipeBrowserProcessLauncher.Windows.cs","lineNumber":241,"sourceCode":"            }\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        {\n            throw CreateWindowsException(\"CloseHandle\");\n        }\n    }\n\n    private static void TryKillProcessTree(int processId)\n    {\n        try\n        {\n            using var process = Process.GetProcessById(processId);\n            if (!process.HasExited)\n            {\n                process.Kill(entireProcessTree: true);\n            }\n        }\n        catch (ArgumentException)\n        {\n        }\n        catch (InvalidOperationException)\n        {","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Browsers/BrowserLogsPipeBrowserProcessLauncher.Windows.cs#L223-L259","documentation":"The launcher closes OS handles for the tracked browser process and its thread via CloseHandle in CloseWindowsHandle, used during StartWindows. If CloseHandle returns FALSE for a non-zero handle, this Win32Exception-named error is thrown. It indicates a handle could not be released - usually a symptom of double-close or handle corruption.","triggerScenarios":"CloseWindowsHandle(handle) is called by StartWindows with a valid (non-Zero) handle and CloseHandle returns FALSE - e.g. the handle was already closed elsewhere (double-close), or the handle value is invalid.","commonSituations":"An earlier failure path partially cleaned up handles then cleanup closes them again; another component closed the same handle value; handle table corruption; rare OS failures.","solutions":["Check the inner NativeErrorCode (ERROR_INVALID_HANDLE=6 usually means double-close).","Look for code paths in the session that could close the same handles before the launcher's cleanup.","Retry the browser launch - a leaked handle rarely affects subsequent sessions.","Capture a handle-leak diagnostic if this repeats; it can indicate an SDK bug.","Update the Aspire.Hosting.Browsers package."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    await StartTrackedBrowserAsync();\n}\ncatch (Win32Exception ex) when (ex.Message.Contains(\"CloseHandle\"))\n{\n    logger.LogWarning(ex, \"Handle cleanup failed (Win32 {Code}); possible double-close.\", ex.NativeErrorCode);\n}","preventionTips":["Do not close the same OS handles from application code; leave cleanup to the launcher.","If you see repeated ERROR_INVALID_HANDLE, check for double-close paths and report an SDK bug.","Retry the launch; leaked handles rarely break subsequent sessions."],"tags":["windows","handle-cleanup","win32","browser"],"backgroundTag":"process-launch-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"}