BigPizzaV3/CodexPlusPlus · error · TimeoutError

app-server turn 超时

Error message

app-server turn 超时

What it means

_collect_turn waits for turn/completed (or item/completed with a final answer) but the deadline elapses first, meaning the app-server never finished the submitted turn within the configured timeout — the model was still streaming, hung, or died without notification.

Solutions

  1. Raise the turn timeout in the bridge config for long prompts.
  2. Check app-server logs/stderr captured by the reader thread for stalls or crashes.
  3. Retry the turn once; if it repeats, restart the app-server process.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at tools/codex-wechat/codex_wechat.py:536 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/c3ec93167eb7a286. Report an issue: GitHub.

Appendix: source

Thrown at tools/codex-wechat/codex_wechat.py:536

                if item.get("type") == "agentMessage" and item.get("phase") == "final_answer":
                    final_item_id = str(item.get("id") or "")
            elif method == "item/agentMessage/delta":
                if final_item_id and params.get("turnId") == turn_id and params.get("itemId") == final_item_id:
                    final_chunks.append(str(params.get("delta") or ""))
            elif method == "item/completed":
                item = params.get("item") or {}
                if item.get("type") == "agentMessage" and item.get("phase") == "final_answer":
                    text = str(item.get("text") or "")
                    if text:
                        final_chunks = [text]
            elif method == "turn/completed" and params.get("turn", {}).get("id") == turn_id:
                turn = params.get("turn") or {}
                if turn.get("status") == "failed":
                    error = str((turn.get("error") or {}).get("message") or "turn failed")
                completed = True

        if not completed:
            raise TimeoutError("app-server turn 超时")
        if error:
            raise RuntimeError(error)

        reply = "".join(final_chunks).strip()
        return reply or "Codex 没有返回最终答复。"


class CodexRunner:
    def __init__(self, cfg: BridgeConfig):
        self.cfg = cfg
        self.app_server: AppServerCodexClient | None = None
        if cfg.codex.backend == "app-server":
            self.app_server = AppServerCodexClient(cfg)
            atexit.register(self.app_server.close)

    def run(self, user_id: str, prompt: str) -> str:
        if self.app_server:
            try:

View on GitHub (pinned to b1ed92e5e4)