openai/codex · error · anyhow::Error

pid-managed app server {pid} has no recorded start time

Error message

pid-managed app server {pid} has no recorded start time

What it means

read_process_start_time treats a ps exit code of 0 with empty stdout as a broken fingerprint: the daemon records the process's lstart string as the identity of the managed server (PidRecord.process_start_time), and an empty one cannot be compared later during stale-record detection. Standard procps always prints a start time for a live pid, so an empty result points at a non-standard ps, a procfs that hides start times, or an exotic patched procps build.

Source

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

    Ok(EmptyPidReservation::Stale)
}

#[cfg(unix)]
async fn read_process_start_time(pid: u32) -> Result<String> {
    let output = Command::new("ps")
        .args(["-p", &pid.to_string(), "-o", "lstart="])
        .output()
        .await
        .context("failed to invoke ps for pid-managed app server")?;
    if !output.status.success() {
        bail!("failed to read start time for pid-managed app server {pid}");
    }

    let start_time = String::from_utf8(output.stdout)
        .context("pid-managed app server start time was not utf-8")?;
    let start_time = start_time.trim();
    if start_time.is_empty() {
        bail!("pid-managed app server {pid} has no recorded start time");
    }
    Ok(start_time.to_string())
}

#[cfg(all(test, unix))]
#[path = "pid_tests.rs"]
mod tests;

View on GitHub (pinned to 339751715c)

Solutions

  1. Run 'ps -p <pid> -o lstart=' by hand for a live pid — if it prints nothing, fix or replace the ps implementation (install full procps).
  2. Check /proc mount options (hidepid) and container seccomp/apparmor profiles that starve ps of process data.
  3. Move the daemon to a host with a standard procps if the environment cannot report start times.
  4. Read the appended stderr log tail to rule out an app-server crash masquerading as a fingerprint failure.
Defensive patterns

Strategy: validation

Validate before calling

// must print a start date before relying on the daemon
let out = std::process::Command::new("ps")
    .args(["-p", "1", "-o", "lstart="])
    .output()?;
if out.stdout.trim().is_empty() {
    anyhow::bail!("ps reports no start time on this host; pid records would be unusable");
}

Try / catch

Treat like [44]: on Err print the anyhow chain (stderr tail included), verify ps behavior manually, then retry start once the environment reports lstart.

Prevention

When it happens

Trigger: Same call sites as [44]: start() recording the spawned child (pid.rs:200) or process_matches_record revalidating a pid (pid.rs:582), where 'ps -p <pid> -o lstart=' exits 0 but prints only whitespace.

Common situations: Hardened hosts with hidepid or restricted /proc mounts; minimal or custom ps builds in containers; enterprise/NAS distros shipping a patched procps that accepts the flag but emits nothing.

Related errors


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