BigPizzaV3/CodexPlusPlus · error · anyhow::Error
等待 Codex 回复超时
Error message
等待 Codex 回复超时
What it means
run_turn drives one Codex turn over the app-server JSON-RPC stdio protocol and waits until both the turn/start response arrives and a turn/completed (or idle thread/status/changed) notification is seen, bounded by TURN_TIMEOUT. This error means the deadline expired first: Codex never answered or never finished the turn within the budget.
Source
Thrown at crates/codex-plus-core/src/connect/app_server.rs:145
}
self.write_json(&json!({
"jsonrpc": "2.0",
"id": id,
"method": "turn/start",
"params": params
}))
.await?;
let mut response_received = false;
let mut turn_completed = false;
let mut reply_parts = Vec::new();
let mut model = self.config.model.trim().to_string();
let mut usage = TurnUsage::default();
let deadline = tokio::time::Instant::now() + TURN_TIMEOUT;
while !response_received || !turn_completed {
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
if remaining.is_zero() {
bail!("等待 Codex 回复超时");
}
let message = self.read_message(remaining).await?;
if is_server_request(&message) {
self.reject_server_request(&message).await?;
continue;
}
if response_id(&message) == Some(id) {
if let Some(error) = rpc_error(&message) {
bail!("Codex turn/start 失败:{error}");
}
let result = message.get("result").cloned().unwrap_or(Value::Null);
if extract_turn_id(&result).is_none() {
bail!("Codex turn/start 未返回 turn id");
}
if model.is_empty() {
model = extract_model(&result).unwrap_or_default();
}
if let Some(reported_usage) = extract_turn_usage(&result) {View on GitHub (pinned to f2074595a2)
Solutions
- Retry the turn with a smaller prompt or less requested output so it finishes inside the budget
- Run one manual codex turn to confirm login and health before starting the connector
- Raise TURN_TIMEOUT in the crate if the workload legitimately runs long
- Keep codex-plus-core and the codex app-server on matched versions
Defensive patterns
Strategy: retry
Try / catch
let reply = match server.run_turn(&thread_id, prompt).await {
Ok(r) => r,
Err(e) if e.to_string().contains("等待 Codex 回复超时") => {
server.close().await;
let mut server = CodexAppServer::start(config).await?;
server.run_turn(&thread_id, trimmed(prompt)).await?
}
Err(e) => return Err(e),
}; Prevention
- Keep prompts bounded so turns finish well inside TURN_TIMEOUT
- Verify codex login before starting long-running connectors
- Pin matched codex and codex-plus-core versions
When it happens
Trigger: A long generation exceeding TURN_TIMEOUT; the codex app-server hung on network or auth; the completion notification was opted out or used a method the loop does not match, so turn_completed never became true.
Common situations: Slow model or oversized prompt; codex CLI waiting for login or authorization; version skew where the app-server emits different completion events than this crate matches.
Related errors
- Codex turn/start 失败:{error}
- Codex turn/start 未返回 turn id
- {error}
- Codex app-server {method} 请求超时
- Codex app-server 已关闭{}
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@f2074595a2 (2026-08-23).
Data as JSON: /api/errors/d25adb3ab7901dea.
Report an issue: GitHub.