{"record":{"id":"5b4aee0cb07abc53","repo":"openai/codex","slug":"pid-managed-updater-loop-is-unsupported-on-this-pl","errorCode":null,"errorMessage":"pid-managed updater loop is unsupported on this platform","messagePattern":"pid-managed updater loop is unsupported on this platform","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/app-server-daemon/src/update_loop.rs","lineNumber":84,"sourceCode":"        ClientRouteClass::Other,\n    );\n    if sleep_or_terminate(INITIAL_UPDATE_DELAY, &mut terminate).await {\n        return Ok(());\n    }\n    loop {\n        match update_once(&http, &running_updater_identity, &mut terminate).await {\n            Ok(UpdateLoopControl::Continue) | Err(_) => {}\n            Ok(UpdateLoopControl::Stop) => return Ok(()),\n        }\n        if sleep_or_terminate(UPDATE_INTERVAL, &mut terminate).await {\n            return Ok(());\n        }\n    }\n}\n\n#[cfg(not(unix))]\npub(crate) async fn run(_http_client_factory: HttpClientFactory) -> Result<()> {\n    bail!(\"pid-managed updater loop is unsupported on this platform\")\n}\n\n#[cfg(unix)]\nasync fn sleep_or_terminate(duration: Duration, terminate: &mut Signal) -> bool {\n    tokio::select! {\n        _ = sleep(duration) => false,\n        _ = terminate.recv() => true,\n    }\n}\n\n#[cfg(unix)]\nenum UpdateLoopControl {\n    Continue,\n    Stop,\n}\n\n#[cfg(unix)]\nasync fn update_once(","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/app-server-daemon/src/update_loop.rs#L66-L102","documentation":"update_loop::run has two cfg-gated bodies. The Unix implementation installs a SIGTERM handler, downloads the installer, and re-execs the managed binary; the cfg(not(unix)) stub exists so the crate compiles on Windows and immediately bails with this message. It fires when the pid-managed updater loop (the daemon's pid-update-loop entry) is started on a non-Unix platform.","triggerScenarios":"Building or running app-server-daemon on Windows (cfg(not(unix))) and reaching any code path that calls update_loop::run, that is, launching the pid-managed update loop subcommand.","commonSituations":"CI matrices that compile and exercise the daemon on windows-latest; developers on Windows trying the daemon workflow; cross-platform refactors that compile fine but invoke Unix-only functionality.","solutions":["Run the pid-managed updater loop only on macOS or Linux; on Windows use the platform-supported update path instead.","If you own the call site, gate it with #[cfg(unix)] so Windows builds never reach the stub.","If Windows support is required, implement the loop with Windows primitives (job objects, console control handlers); the bail exists because the Unix signal-plus-exec design does not translate."],"exampleFix":"// before\nlet handle = tokio::spawn(run_updater(http)); // reaches the stub on Windows\n\n// after\n#[cfg(unix)]\nlet handle = tokio::spawn(run_updater(http));\n#[cfg(not(unix))]\nlet handle = std::future::ready(Ok(())); // pid-managed updater is Unix-only","handlingStrategy":"validation","validationCode":"if !cfg!(unix) {\n    // The pid-managed updater loop is Unix-only; skip instead of erroring.\n    return Ok(());\n}\nupdate_loop::run(http).await","typeGuard":null,"tryCatchPattern":"if let Err(err) = update_loop::run(http).await {\n    if err.to_string().contains(\"unsupported on this platform\") {\n        tracing::info!(\"skipping pid-managed updater on this platform\");\n        return Ok(());\n    }\n    return Err(err);\n}","preventionTips":["Gate daemon updater entry points with #[cfg(unix)] at CLI dispatch level, not at the innermost call.","Mark pid-update-loop as Unix-only in CI matrices and skip its tests with cfg assertions.","When adding Unix-specific machinery (signals, exec), add matching cfg gates at every consumer."],"tags":["platform-support","windows","updater","daemon","cfg-gating"],"backgroundTag":"unsupported-platform","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}