openai/codex · error · anyhow::Error

standalone Codex updater exited with status {status}

Error message

standalone Codex updater exited with status {status}

What it means

install_latest_standalone fetches the install script and pipes it into /bin/sh -s with stdout and stderr set to null, then waits for the child. A non-zero exit status produces this error. The child is the standalone Codex installer, so the status is whatever the shell returned after the script failed, and because stderr is discarded the status code is the only diagnostic. The update loop swallows per-cycle errors and retries hourly, so this message surfaces mainly in tests or explicit update_once calls.

Source

Thrown at codex-rs/app-server-daemon/src/update_loop.rs:196

        .context("failed to invoke standalone Codex updater")?;
    let mut stdin = child
        .stdin
        .take()
        .context("standalone Codex updater stdin was unavailable")?;
    stdin
        .write_all(&script)
        .await
        .context("failed to pass standalone Codex updater to shell")?;
    drop(stdin);
    let status = child
        .wait()
        .await
        .context("failed to wait for standalone Codex updater")?;

    if status.success() {
        Ok(())
    } else {
        anyhow::bail!("standalone Codex updater exited with status {status}")
    }
}

#[cfg(unix)]
async fn fetch_installer_script(http: &impl InstallerHttp) -> Result<Vec<u8>> {
    match http.get(INSTALL_URL).await? {
        InstallerResponse::Success(body) => Ok(body),
        InstallerResponse::Unsuccessful { status } => {
            anyhow::bail!("standalone Codex updater request failed with status {status}")
        }
    }
}

#[cfg(unix)]
#[derive(Clone, Debug, PartialEq, Eq)]
enum InstallerResponse {
    Success(Vec<u8>),
    Unsuccessful { status: u16 },

View on GitHub (pinned to 339751715c)

Solutions

  1. Reproduce with visible output: run curl -fsSL https://chatgpt.com/codex/install.sh | sh -s in the same environment; the daemon discards the script's stderr, a manual run shows it.
  2. Check write permissions on the install directory and free disk space.
  3. Verify the tools the script relies on exist on PATH (sh, curl or wget, tar, uname).
  4. If a proxy is in play, confirm it permits every host the script downloads from, not only chatgpt.com.
  5. As a maintainer, pipe child stderr and include it in the error so future failures are diagnosable from the daemon logs.

Example fix

// before
.stdout(Stdio::null())
.stderr(Stdio::null())

// after (diagnosable installer failures)
.stderr(Stdio::piped())
// ...after wait():
if !status.success() {
    anyhow::bail!("standalone Codex updater exited with status {status}: {stderr}");
}
Defensive patterns

Strategy: try-catch

Validate before calling

# Run the exact installer by hand before blaming the daemon:
curl -fsSL https://chatgpt.com/codex/install.sh | sh -s
echo $?

Try / catch

if let Err(err) = update_once_result {
    if err.to_string().contains("updater exited with status") {
        // Installer child failed: diagnose the environment (permissions,
        // proxy, disk) and let the hourly loop retry; do not crash the daemon.
        tracing::warn!(error = err.to_string(), "standalone install failed");
    }
}

Prevention

When it happens

Trigger: An update tick where the installer script exits non-zero: its internal download or checksum verification fails, the install directory is not writable, helper binaries the script needs (curl, tar, uname) are missing, the disk is full, or set -e aborts on any failed command.

Common situations: Read-only or root-owned install prefix; corporate proxies that let the script download start but block later hosts; minimal CI containers without ca-certificates; disk quota exhaustion mid-install.

Related errors


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