openai/codex · error · anyhow::Error

pid-managed updater shutdown is unsupported on this platform

Error message

pid-managed updater shutdown is unsupported on this platform

What it means

The pid update loop ('app-server daemon pid-update-loop', see command_args at pid.rs:421) is spawned with setsid and torn down by killing its whole process group via kill(-pid, SIGKILL) on Unix. On non-Unix targets this group-kill stub bails unconditionally. It is reached through PidBackend::force_terminate_process when command_kind is PidCommandKind::UpdateLoop (pid.rs:445-449).

Source

Thrown at codex-rs/app-server-daemon/src/backend/pid.rs:573

    if err.raw_os_error() == Some(libc::ESRCH) {
        return Ok(());
    }
    Err(err).with_context(|| format!("failed to force terminate pid-managed updater group {pid}"))
}

#[cfg(not(unix))]
fn terminate_process(_pid: u32) -> Result<()> {
    bail!("pid-managed app-server shutdown is unsupported on this platform")
}

#[cfg(not(unix))]
fn force_terminate_process(_pid: u32) -> Result<()> {
    bail!("pid-managed app-server shutdown is unsupported on this platform")
}

#[cfg(not(unix))]
fn force_terminate_process_group(_pid: u32) -> Result<()> {
    bail!("pid-managed updater shutdown is unsupported on this platform")
}

#[cfg(unix)]
async fn process_matches_record(record: &PidRecord) -> Result<bool> {
    if !process_exists(record.pid) {
        return Ok(false);
    }

    match read_process_start_time(record.pid).await {
        Ok(start_time) => Ok(start_time == record.process_start_time),
        Err(_err) if !process_exists(record.pid) => Ok(false),
        Err(err) => Err(err),
    }
}

#[cfg(not(unix))]
async fn process_matches_record(_record: &PidRecord) -> Result<bool> {
    Ok(false)

View on GitHub (pinned to 339751715c)

Solutions

  1. Run the updater lifecycle on a Unix platform — process groups (setsid + kill(-pid)) are POSIX-only.
  2. Route through the public run_pid_update_loop()/run() APIs so ensure_supported_platform rejects non-Unix first.
  3. cfg-gate updater teardown call sites with #[cfg(unix)] and degrade gracefully elsewhere.
  4. Don't port the group-kill expectation to Windows; there is no equivalent stub-free path in this crate.
Defensive patterns

Strategy: validation

Validate before calling

if !cfg!(unix) {
    anyhow::bail!("updater process-group shutdown requires Unix");
}

Try / catch

None — unconditional bail on non-Unix. Prevent at dispatch with a platform check instead of catching downstream.

Prevention

When it happens

Trigger: Stopping or restarting the managed updater on a non-Unix build; any test driving update-loop teardown on Windows. The Unix twin at pid.rs:547 sends SIGKILL to the process group and treats ESRCH as success, never yielding this message.

Common situations: Update-loop lifecycle invoked on Windows hosts; cross-platform tooling assuming process-group semantics; CI on non-Unix runners touching updater teardown code.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/ac0e1a555f21ee0c. Report an issue: GitHub.