nikivdev/code · error · anyhow::Error
codex app-server response timed out
Error message
codex app-server response timed out
What it means
codex_read_response polls the codex app-server child process stdout for a JSON-RPC response with a specific id, but only until a deadline. When the deadline elapses before the expected response arrives, it aborts with this message instead of blocking forever. It is a deliberate timeout guard against a hung or stuck app-server process.
Source
Thrown at src/skills.rs:1118
source: Option<String>,
}
fn codex_write_msg(writer: &mut dyn Write, msg: &serde_json::Value) -> Result<()> {
let mut line = serde_json::to_string(msg)?;
line.push('\n');
writer.write_all(line.as_bytes())?;
writer.flush()?;
Ok(())
}
fn codex_read_response(
lines: &mut std::io::Lines<std::io::BufReader<std::process::ChildStdout>>,
expected_id: u64,
deadline: Instant,
) -> Result<serde_json::Value> {
loop {
if Instant::now() >= deadline {
bail!("codex app-server response timed out");
}
let line = match lines.next() {
Some(Ok(line)) => line,
Some(Err(err)) => bail!("failed to read from codex app-server: {}", err),
None => bail!("codex app-server closed stdout unexpectedly"),
};
if line.trim().is_empty() {
continue;
}
let msg: serde_json::Value = serde_json::from_str(&line)
.with_context(|| format!("invalid JSON from codex app-server: {}", line))?;
if msg.get("id").and_then(|v| v.as_u64()) == Some(expected_id) {
if let Some(err) = msg.get("error") {
let message = err
.get("message")
.and_then(|v| v.as_str())
.unwrap_or("unknown codex app-server error");
bail!("codex app-server error: {}", message);View on GitHub (pinned to a747e741ae)
Solutions
- Check that the codex app-server process is alive and responsive (kill hung instances and retry)
- Verify the codex binary version matches the protocol this tool expects; upgrade or downgrade codex
- Re-run the command after freeing system resources; the deadline is fixed so a transiently slow machine can cause this
- Add logging around the request to confirm the request id sent matches the one codex_read_response waits for
Example fix
// before: waiting on a hung server with no diagnosis
bail!("codex app-server response timed out");
// after: surface the elapsed time and hint at the hung process
bail!("codex app-server response timed out after {:?} (is the codex app-server hung?)", deadline.duration_since(Instant::now())); Defensive patterns
Strategy: retry
Validate before calling
// check the codex app-server is responsive before the call
if let Ok(status) = std::process::Command::new("pgrep").args(["-f", "codex app-server"]).status() {
if !status.success() { eprintln!("codex app-server not running; expect timeout"); }
} Try / catch
match reload_codex_skills_for_cwd() {
Ok(skills) => apply(skills),
Err(e) if e.to_string().contains("timed out") => {
// kill wedged server, back off, retry once
kill_codex_app_server();
std::thread::sleep(RETRY_DELAY);
retry_reload()?;
}
Err(e) => return Err(e),
} Prevention
- Keep the codex binary version aligned with the client protocol so ids/methods match
- Add health checks or pings to the app-server before issuing real requests
- Avoid issuing requests while the machine is under heavy load; the deadline is fixed
- Capture the child's stderr so hangs can be diagnosed quickly
When it happens
Trigger: Calling reload_codex_skills_for_cwd (which sends a request to the codex app-server via codex_read_response) when the app-server accepts the request but never sends back a response with the expected id before the deadline; a wedged or extremely slow codex process; a request id mismatch so the expected reply never matches.
Common situations: Codex app-server is frozen or overloaded; the codex binary version speaks a different protocol so responses carry unexpected ids; system under heavy load makes the child slow to answer; stdout produces unrelated chatter so the matching id never appears before timeout.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- failed to read from codex: {}
- codex app-server response timed out
- failed to read from codex app-server: {}
- codex app-server closed stdout unexpectedly
- codex app-server closed stdout unexpectedly
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/3f50c4a93afe7b39.
Report an issue: GitHub.