{"record":{"id":"ff1baf7beede4ec8","repo":"openai/codex","slug":"pid-managed-app-server-shutdown-is-unsupported-on","errorCode":null,"errorMessage":"pid-managed app-server shutdown is unsupported on this platform","messagePattern":"pid-managed app-server shutdown is unsupported on this platform","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/app-server-daemon/src/backend/pid.rs","lineNumber":563,"sourceCode":"\n#[cfg(unix)]\nfn force_terminate_process_group(pid: u32) -> Result<()> {\n    let raw_pid = libc::pid_t::try_from(pid)\n        .with_context(|| format!(\"pid-managed updater pid {pid} is out of range\"))?;\n    let result = unsafe { libc::kill(-raw_pid, libc::SIGKILL) };\n    if result == 0 {\n        return Ok(());\n    }\n    let err = std::io::Error::last_os_error();\n    if err.raw_os_error() == Some(libc::ESRCH) {\n        return Ok(());\n    }\n    Err(err).with_context(|| format!(\"failed to force terminate pid-managed updater group {pid}\"))\n}\n\n#[cfg(not(unix))]\nfn terminate_process(_pid: u32) -> Result<()> {\n    bail!(\"pid-managed app-server shutdown is unsupported on this platform\")\n}\n\n#[cfg(not(unix))]\nfn force_terminate_process(_pid: u32) -> Result<()> {\n    bail!(\"pid-managed app-server shutdown is unsupported on this platform\")\n}\n\n#[cfg(not(unix))]\nfn force_terminate_process_group(_pid: u32) -> Result<()> {\n    bail!(\"pid-managed updater shutdown is unsupported on this platform\")\n}\n\n#[cfg(unix)]\nasync fn process_matches_record(record: &PidRecord) -> Result<bool> {\n    if !process_exists(record.pid) {\n        return Ok(false);\n    }\n","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/app-server-daemon/src/backend/pid.rs#L545-L581","documentation":"PidBackend shuts the managed app-server down by sending SIGTERM through libc::kill on Unix. On non-Unix targets there is no signal implementation, so terminate_process is a #[cfg(not(unix))] stub that unconditionally bails with this message to keep the crate cross-compilable. The daemon's public entry points already reject non-Unix platforms up front (ensure_supported_platform in codex-rs/app-server-daemon/src/lib.rs:242), so hitting this means the pid backend was reached directly on a Windows build.","triggerScenarios":"Compiling codex-app-server-daemon for Windows (or any non-Unix target) and driving a stop path that reaches PidBackend::terminate_process (codex-rs/app-server-daemon/src/backend/pid.rs:438), e.g. LifecycleCommand::Stop with a pid record present. On Unix the real SIGTERM implementation at pid.rs:517 is used instead and never produces this error.","commonSituations":"Running the daemon crate or its unit tests on a Windows dev machine; cross-compiling with cargo build --target *-windows-* and invoking lifecycle stop; reusing a CODEX_HOME whose state dir still holds a pid file written from WSL/Linux so a stop is attempted.","solutions":["Run the app-server daemon on macOS or Linux — the lifecycle is Unix-only by design and the platform gate in lib.rs is intentional.","Call the public codex_app_server_daemon::run()/bootstrap() APIs instead of the pid backend directly, so the unsupported-platform check fires first with the clearer umbrella message.","cfg-gate your own call sites with #[cfg(unix)] and emit a 'daemon stop requires a Unix host' error on other targets rather than letting the backend stub bail.","Clear stale state (<CODEX_HOME>/state/*.pid and *.pid.lock left by another platform) before reusing the same CODEX_HOME."],"exampleFix":"// before: compiles everywhere, bails at runtime on Windows\nbackend.stop().await?;\n\n// after: gate the call site so non-Unix gets a clear, local error\n#[cfg(unix)]\n{\n    backend.stop().await?;\n}\n#[cfg(not(unix))]\nanyhow::bail!(\"app-server daemon stop requires a Unix host\");","handlingStrategy":"validation","validationCode":"// run before touching any daemon lifecycle API\nif !cfg!(unix) {\n    anyhow::bail!(\"codex app-server daemon lifecycle requires a Unix platform\");\n}","typeGuard":null,"tryCatchPattern":"Not recoverable by catching: the bail is unconditional on non-Unix. If forced, branch on cfg!(unix) and degrade to a no-op with a warning instead of unwrap/expect on the Result.","preventionTips":["Compile-time gate every daemon call site with #[cfg(unix)] so the code cannot exist on Windows builds.","Keep daemon subcommands out of the Windows CLI surface rather than erroring at runtime.","Include a non-Unix target in CI to catch accidental reliance on Unix-only lifecycle code."],"tags":["rust","codex","daemon","platform-support","windows","shutdown"],"backgroundTag":"unsupported-platform","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}