{"record":{"id":"078495a9b2b0568c","repo":"microsoft/aspire","slug":"failed-to-update-process-thread-attribute-list","errorCode":null,"errorMessage":"Failed to update process thread attribute list","messagePattern":"Failed to update process thread attribute list","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Processes/WindowsProcessInterop.cs","lineNumber":413,"sourceCode":"            try\n            {\n                var handles = inheritable.ToArray();\n                var pinnedHandles = GCHandle.Alloc(handles, GCHandleType.Pinned);\n                var pinnedJobHandles = default(GCHandle);\n                var jobHandleRefAdded = false;\n\n                try\n                {\n                    if (!UpdateProcThreadAttribute(\n                        attrList,\n                        0,\n                        ProcThreadAttributeHandleList,\n                        pinnedHandles.AddrOfPinnedObject(),\n                        (nint)(nint.Size * handles.Length),\n                        nint.Zero,\n                        nint.Zero))\n                    {\n                        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), \"Failed to update process thread attribute list\");\n                    }\n\n                    if (jobHandle is not null)\n                    {\n                        jobHandle.DangerousAddRef(ref jobHandleRefAdded);\n                        var jobHandles = new[] { jobHandle.DangerousGetHandle() };\n                        pinnedJobHandles = GCHandle.Alloc(jobHandles, GCHandleType.Pinned);\n\n                        if (!UpdateProcThreadAttribute(\n                            attrList,\n                            0,\n                            ProcThreadAttributeJobList,\n                            pinnedJobHandles.AddrOfPinnedObject(),\n                            (nint)(nint.Size * jobHandles.Length),\n                            nint.Zero,\n                            nint.Zero))\n                        {\n                            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), \"Failed to add job object to process thread attribute list\");","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Processes/WindowsProcessInterop.cs#L395-L431","documentation":"After initializing the PROC_THREAD_ATTRIBUTE_LIST, the Aspire CLI adds the inheritable-handle list to it via UpdateProcThreadAttribute(ProcThreadAttributeHandleList). This error is thrown when that native update call fails, wrapped with the last Win32 error. It means the child process cannot be started with a restricted, explicit set of inheritable handles.","triggerScenarios":"Spawning a child process on Windows with explicit handle inheritance where UpdateProcThreadAttribute with ProcThreadAttributeHandleList returns false — typically when pinned handle buffer pointers/sizes are invalid or the attribute list was not properly initialized.","commonSituations":"One or more handles in the inheritable list are invalid or already closed (race between handle collection and process start); memory pressure corrupting pinned buffers; security software interfering with process-creation attribute APIs.","solutions":["Inspect the inner Win32Exception code (e.g. ERROR_INVALID_HANDLE indicates a handle in the list was closed before the spawn).","Retry the operation — transient handle races can resolve on a second attempt.","Update the Aspire CLI; if reproducible, this indicates a handle-lifetime bug in the interop layer worth reporting.","Ensure no antivirus/EDR policy blocks UpdateProcThreadAttribute usage in your environment."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (Win32Exception ex) when (ex.ErrorCode == unchecked((int)0x80070006)) // ERROR_INVALID_HANDLE\n{\n    // A handle in the inherit list closed mid-setup; retry the spawn once.\n    return RetrySpawnOnce();\n}","preventionTips":["Ensure inheritable handles stay open for the whole spawn window.","Avoid concurrently closing handles used for child spawn.","Retry transient spawn failures once before surfacing."],"tags":["windows","win32","process-management","interop","handles"],"backgroundTag":"win32-api-call-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"}