openai/codex · warning · anyhow::Error
Snapshot command timed out for {shell_name}
Error message
Snapshot command timed out for {shell_name} What it means
run_script_with_timeout wraps the snapshot shell process in tokio::time::timeout with SNAPSHOT_TIMEOUT = 10 seconds (shell_snapshot.rs:45), with kill_on_drop(true) so the child is reaped when the future is dropped. The error fires when sourcing rcfiles plus emitting the snapshot exceeds those 10s. Both snapshot creation and snapshot validation (which re-sources the written file) run through this budget.
Source
Thrown at codex-rs/core/src/shell_snapshot.rs:302
// Handler is kept as guard to control the drop. The `mut` pattern is required because .args()
// returns a ref of handler.
let mut handler = Command::new(&args[0]);
codex_protocol::shell_environment::scrub_non_inheritable_env_vars(handler.as_std_mut());
handler.args(&args[1..]);
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>,View on GitHub (pinned to 339751715c)
Solutions
- Time your shell startup (zsh -i -c 'exit' with a prompt timer, or time zsh -lc true) and trim/lazy-load the slow rcfile parts (defer nvm, conda hooks)
- Move network-touching init out of rcfiles or cache their results
- Skip heavy init when non-interactive so snapshot runs stay lean
- If startup legitimately needs more, disable shell snapshots rather than fighting the fixed 10s budget (the timeout constant is not user-configurable)
Example fix
# ~/.zshrc — before
source ~/.nvm/nvm.sh # seconds of startup cost
# after — lazy-load so snapshot runs stay fast
if [[ -n "$USE_NVM" ]]; then source ~/.nvm/nvm.sh; else
nvm() { unfunction nvm; source ~/.nvm/nvm.sh; nvm "$@"; }
fi Defensive patterns
Strategy: fallback
Validate before calling
// Measure login-shell startup before enabling snapshots // e.g. in shell: TIMEFMT='%E'; time zsh -lc true — keep it well under the 10s budget
Try / catch
match try_create(...).await {
Err("write_failed") | Err("validation_failed") => {
warn_and_continue_without_snapshot(); }
ok => ok,
} Prevention
- Keep login-shell startup under a few seconds (lazy-load nvm/conda/pyenv)
- Remove network calls from rcfiles or cache their results
- The timeout is fixed at 10s (SNAPSHOT_TIMEOUT) — don't design dotfiles that need more
- Monitor the codex.shell_snapshot counter with failure_reason tags to catch envs that chronically time out
When it happens
Trigger: Login-shell (-lc) snapshot run where rcfiles take >10s: nvm/pyenv/conda/rbenv init, network calls (version managers, proxy checks, prompt themes fetching data), sleeps, or huge shell histories; also a validation run re-sourcing an enormous generated snapshot.
Common situations: Heavy developer dotfiles (nvm.sh alone can take seconds), corporate login scripts, DNS/proxy stalls inside rcfiles, resource-starved CI or containers making shell startup crawl.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Shell snapshot not supported yet for {shell_type:?}
- Shell snapshotting is not yet supported for {shell_type:?}
- Snapshot output missing marker {marker}
- Snapshot command exited with status {status}: {stderr}
- network proxy attribution frame timed out
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/e806e7133bb852ca.
Report an issue: GitHub.