{"record":{"id":"64f75ed90d3757f4","repo":"BigPizzaV3/CodexPlusPlus","slug":"cannot-verify-launcher-process-identity-pid","errorCode":null,"errorMessage":"Cannot verify launcher process identity: {pid}","messagePattern":"Cannot verify launcher process identity: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/watcher.rs","lineNumber":568,"sourceCode":"#[cfg(windows)]\npub struct LauncherExitSnapshot {\n    processes: Vec<(u32, u64)>,\n}\n\n#[cfg(windows)]\nimpl LauncherExitSnapshot {\n    pub fn capture() -> anyhow::Result<Self> {\n        let processes = crate::windows_integration::enumerate_processes();\n        let ids = filter_killable_launcher_processes(\n            processes.iter().map(|p| (p.process_id, p.parent_process_id, p.exe_file.as_str())),\n            std::process::id(),\n        );\n        let mut captured = Vec::new();\n        for pid in ids {\n            if let Some(birth) = crate::windows_integration::process_birth_id(pid) {\n                captured.push((pid, birth));\n            } else {\n                anyhow::bail!(\"Cannot verify launcher process identity: {pid}\");\n            }\n        }\n        Ok(Self { processes: captured })\n    }\n\n    pub fn wait_for_exit(self, timeout: Duration) -> anyhow::Result<()> {\n        let deadline = std::time::Instant::now() + timeout;\n        loop {\n            let remaining = launcher_incarnations_still_running(\n                &self.processes,\n                |pid| crate::windows_integration::process_birth_id(pid),\n            );\n            if remaining.is_empty() {\n                return Ok(());\n            }\n            anyhow::ensure!(\n                std::time::Instant::now() < deadline,\n                \"Previous launcher has not exited; no process was forcibly terminated\"","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/watcher.rs#L550-L586","documentation":"capture() snapshots launcher process identity by reading each PID's birth id via the Windows integration layer. If process_birth_id returns None for any PID, the process identity cannot be verified and capture aborts with this error so the watcher never waits on the wrong process.","triggerScenarios":"Calling capture with a PID that has already exited, or a PID for which the OS denies/omits creation-time info (recycled PID, protected process, invalid pid).","commonSituations":"Launcher crashed before the watcher could snapshot it; PID reuse gave a stale id; spawning raced with process exit; passing an incorrect pid parsed from stale state.","solutions":["Verify the launcher is still running right before calling capture and pass the pid of a live process","Re-scan the process list to obtain a fresh pid and retry capture","Treat the error as transient: retry capture shortly after spawn, or skip waiting for the dead launcher and report it as exited"],"exampleFix":"// before\nlet snapshot = LauncherSnapshot::capture(&[stale_pid], ...)?;\n// after\nif crate::windows_integration::process_birth_id(pid).is_some() {\n    let snapshot = LauncherSnapshot::capture(&[pid], ...)?;\n} else {\n    // respawn launcher and recapture with fresh pid\n}","handlingStrategy":"retry","validationCode":"fn pid_alive(pid: u32) -> bool {\n    crate::windows_integration::process_birth_id(pid).is_some()\n}","typeGuard":"fn verified_pid(pid: u32) -> Option<u32> {\n    crate::windows_integration::process_birth_id(pid).map(|_| pid)\n}","tryCatchPattern":"match LauncherSnapshot::capture(&[pid], ...) {\n    Err(e) if e.to_string().contains(\"Cannot verify launcher process identity\") => {\n        // process exited before snapshot; rescan and retry once\n    }\n    other => other?,\n}","preventionTips":["Capture immediately after spawning the launcher to minimize the race window","Never cache pids across sessions; re-derive them from the process list","Treat capture failure as 'launcher died early' and surface that to the user"],"tags":["windows","process","race-condition"],"backgroundTag":"resource-not-found","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}