{"record":{"id":"9727fe05d983121f","repo":"jdx/mise","slug":"could-not-find-the-suspended-description-command-s","errorCode":null,"errorMessage":"could not find the suspended description command's primary thread","messagePattern":"could not find the suspended description command's primary thread","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/describe_command/windows_job.rs","lineNumber":87,"sourceCode":"        while found {\n            if entry.th32OwnerProcessID == child.id() {\n                // SAFETY: request only resume access to the child's thread.\n                let thread = unsafe { OpenThread(THREAD_SUSPEND_RESUME, 0, entry.th32ThreadID) };\n                if thread.is_null() {\n                    return Err(std::io::Error::last_os_error().into());\n                }\n                // SAFETY: the returned handle is valid and uniquely owned.\n                let thread = unsafe { OwnedHandle::from_raw_handle(thread) };\n                // SAFETY: the child is already assigned to our kill-on-close job.\n                if unsafe { ResumeThread(thread.as_raw_handle()) } == u32::MAX {\n                    return Err(std::io::Error::last_os_error().into());\n                }\n                return Ok(());\n            }\n            // SAFETY: the snapshot and writable entry remain valid.\n            found = unsafe { Thread32Next(snapshot.as_raw_handle(), &mut entry) } != 0;\n        }\n        bail!(\"could not find the suspended description command's primary thread\")\n    }\n\n    pub(super) fn kill(&self) {\n        // SAFETY: the owned handle always refers to this command's job.\n        unsafe { TerminateJobObject(self.0.as_raw_handle(), 1) };\n    }\n}\n\npub(super) fn spawn(command: &mut Command) -> Result<(Child, Job)> {\n    let job = Job::new()?;\n    command.creation_flags(CREATE_SUSPENDED);\n    let mut child = command.spawn()?;\n    if let Err(error) = job.start(&child) {\n        // A failure must not leave either a suspended child or an unowned tree.\n        let _ = child.kill();\n        let _ = child.wait();\n        return Err(error);\n    }","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/describe_command/windows_job.rs#L69-L105","documentation":"Thrown by `WindowsJob::start` when, after creating the suspended description command process inside a Windows job object, a Toolhelp32 snapshot traversal (Thread32First/Thread32Next) finds no thread to identify as the command's primary thread. Without that thread handle the library cannot resume/track the process, so it aborts startup.","triggerScenarios":"On Windows only: process creation succeeded but the snapshot enumeration returned no threads belonging to the new process — typically a race where the process exited before enumeration, or snapshot creation raced process initialization.","commonSituations":"Antivirus or security software terminating newly spawned processes; extremely fast-failing description commands on Windows; system resource pressure making CreateToolhelp32Snapshot return a stale/empty snapshot.","solutions":["Retry the description command; a transient race with process startup is the usual cause.","Check whether antivirus/EDR is killing freshly spawned processes and add an exclusion for the mise binary.","Verify the command itself does not exit instantly with an error before threads can be enumerated.","Report a bug if reproducible: the snapshot loop should handle this process-creation race internally."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// on Err(\"could not find ... primary thread\") on Windows: retry once\n// before assuming the command itself is broken","preventionTips":["Keep antivirus exclusions for the tool binary.","Avoid commands that exit instantly before threads enumerate.","Retry transient Windows process-start failures once."],"tags":["windows","process","thread","platform-specific"],"backgroundTag":"resource-not-found","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}