BigPizzaV3/CodexPlusPlus · error · RuntimeError

app-server 未启动

Error message

app-server 未启动

What it means

Raised by the app-server client's _send when it tries to write a JSON-RPC message but self.proc or self.proc.stdin is None. It is a sentinel state error meaning the codex app-server subprocess was never spawned (or its stdin pipe is gone), so any request like initialize would be silently lost.

Solutions

  1. Ensure the app-server process is started before sending requests; check that codex is installed and the configured command/args are correct.
  2. Call the client's start/initialize path (e.g. _start) before issuing any RPC and restart the client on failure.
  3. Log self.proc state to confirm whether the process spawn failed or the pipe was closed after exit.
Defensive patterns

Strategy: fallback

When it happens

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

Appendix: source

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

            errors="replace",
            bufsize=1,
        )
        assert self.proc.stdout is not None
        assert self.proc.stderr is not None
        threading.Thread(target=self._reader, args=(self.proc.stdout, "stdout"), daemon=True).start()
        threading.Thread(target=self._reader, args=(self.proc.stderr, "stderr"), daemon=True).start()
        self._request(
            "initialize",
            {
                "clientInfo": {"name": "codex-wechat", "version": "0.1.0"},
                "capabilities": None,
            },
            timeout=20,
        )

    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:

View on GitHub (pinned to b1ed92e5e4)