openai/codex · warning · anyhow::Error

Snapshot command exited with status {status}: {stderr}

Error message

Snapshot command exited with status {status}: {stderr}

What it means

After the snapshot shell process exits, run_script_with_timeout checks output.status.success(); a non-zero exit code triggers this bail with the exit status and captured stderr. The status is from the login-shell run that sources rcfiles and emits the snapshot (or, during validation, from re-sourcing the written snapshot with set -e). Any rcfile error that propagates as a non-zero exit surfaces here.

Source

Thrown at codex-rs/core/src/shell_snapshot.rs:308

    handler.stdin(Stdio::null());
    handler.current_dir(cwd);
    #[cfg(unix)]
    unsafe {
        handler.pre_exec(|| {
            codex_utils_pty::process_group::detach_from_tty()?;
            Ok(())
        });
    }
    handler.kill_on_drop(true);
    let output = timeout(snapshot_timeout, handler.output())
        .await
        .map_err(|_| anyhow!("Snapshot command timed out for {shell_name}"))?
        .with_context(|| format!("Failed to execute {shell_name}"))?;

    if !output.status.success() {
        let status = output.status;
        let stderr = String::from_utf8_lossy(&output.stderr);
        bail!("Snapshot command exited with status {status}: {stderr}");
    }

    Ok(String::from_utf8_lossy(&output.stdout).into_owned())
}

/// Removes shell snapshots that either lack a matching session rollout file or
/// whose rollouts have not been updated within the retention window.
/// The active session id is exempt from cleanup.
pub async fn cleanup_stale_snapshots(
    codex_home: &AbsolutePathBuf,
    active_session_id: ThreadId,
    state_db: Option<StateDbHandle>,
) -> Result<()> {
    let snapshot_dir = codex_home.join(SNAPSHOT_DIR);

    let mut entries = match fs::read_dir(&snapshot_dir).await {
        Ok(entries) => entries,
        Err(err) if err.kind() == ErrorKind::NotFound => return Ok(()),

View on GitHub (pinned to 339751715c)

Solutions

  1. Run zsh -lc true (or bash -lc true) in the same environment — non-zero exit plus the stderr shown in the error pinpoints the failing rcfile line
  2. Fix the rcfile error named in stderr (syntax error, missing command, bad option)
  3. For set -e-style failures, guard the failing command in rcfiles (cmd || true) or make it conditional on interactive shells
  4. Until fixed, disable the shell snapshot feature — failure is non-fatal to the session

Example fix

# ~/.bash_profile — before
source ~/bin/my-init.sh   # exits 1 when tool missing

# after
[[ -f ~/bin/my-init.sh ]] && source ~/bin/my-init.sh || echo "my-init skipped" >&2
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate rcfiles load cleanly before enabling snapshots
// shell: zsh -n ~/.zshrc (syntax) and zsh -lc true (execution) must pass

Try / catch

match write_shell_snapshot(...).await {
    Err(e) if e.chain().any(|c| c.to_string().contains("exited with status")) => {
        log_shell_rc_error(&e); Ok(None) // degrade, session continues
    }
    other => other,
}

Prevention

When it happens

Trigger: Running the snapshot script under zsh/bash -lc where: an rcfile has a syntax error; a sourced script runs under set -e and a command fails; the shell binary itself is broken (missing interpreter, wrong arch); validation run fails because the generated snapshot no longer sources cleanly.

Common situations: Broken dotfiles after an OS or shell upgrade (deprecated options in .zshrc); a failed tool init (missing binary referenced in .bash_profile); shell binaries corrupted or replaced; snapshots generated against a different shell version failing validation on re-source.

Related errors


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