BigPizzaV3/CodexPlusPlus · error · RuntimeError
app-server 已退出,退出码
Error message
app-server 已退出,退出码 {self.proc.returncode} What it means
During _request's wait loop, if the messages queue stays empty for 0.5s the code polls the app-server process; if poll() shows it has terminated, this error reports the exit code. It means the subprocess crashed or exited mid-request, so the pending JSON-RPC call can never be answered.
Solutions
- Check the captured stdout/stderr reader logs for the app-server's crash output (bad config, missing binary, port conflicts).
- Verify the codex binary version supports the requested method/app-server protocol.
- Restart the app-server client and retry; add supervisor logic to respawn the process on unexpected exit.
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at tools/codex-wechat/codex_wechat.py:450 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/5424b3de5f39c02d.
Report an issue: GitHub.
Appendix: source
Thrown at tools/codex-wechat/codex_wechat.py:450
def _send(self, message: dict[str, Any]) -> None:
if not self.proc or not self.proc.stdin:
raise RuntimeError("app-server 未启动")
self.proc.stdin.write(json.dumps(message, ensure_ascii=False) + "\n")
self.proc.stdin.flush()
def _request(self, method: str, params: Any, timeout: int | None = None) -> dict[str, Any]:
req_id = self.next_id
self.next_id += 1
self._send({"id": req_id, "method": method, "params": params})
deadline = time.time() + (timeout or self.cfg.codex.timeout_seconds)
while time.time() < deadline:
try:
msg = self.messages.get(timeout=0.5)
except queue.Empty:
if self.proc and self.proc.poll() is not None:
raise RuntimeError(f"app-server 已退出,退出码 {self.proc.returncode}")
continue
if msg.get("id") == req_id:
if "error" in msg:
raise RuntimeError(f"{method} 失败:{msg['error']}")
return msg.get("result") or {}
# 其它通知留给当前请求外的事件循环自然丢弃。
raise TimeoutError(f"{method} 超时")
def _ensure_thread(self, user_id: str) -> str:
thread_id = self.threads.get(user_id)
if thread_id:
return thread_id
params: dict[str, Any] = {
"cwd": self.cfg.codex.workspace,
"approvalPolicy": self.cfg.codex.approval_policy,
"sandbox": self.cfg.codex.sandbox,
"ephemeral": True,View on GitHub (pinned to b1ed92e5e4)