can1357/oh-my-pi · error · RpcTimeoutError

Timed out waiting for agent_end. Stderr: {self.stderr}

Error message

Timed out waiting for agent_end. Stderr: {self.stderr}

What it means

RpcTimeoutError raised when no agent_end event arrives within the requested (or default 60s) timeout while the process is still alive. Stderr is included to help diagnose a hung server.

Source

Thrown at python/omp-rpc/src/omp_rpc/client.py:1368

                async_errors = self._async_errors.snapshot_from(start_async_error_index)
                if len(async_errors) > 0:
                    raise async_errors[0]

                event_payloads = self._events.snapshot_from(start_index)
                if any(
                    payload.get("type") == "agent_end"
                    and payload.get("isTerminal") is not False
                    for payload in event_payloads
                ):
                    events = tuple(
                        cast(RpcAgentEvent, parse_notification(payload))
                        for payload in event_payloads
                    )
                    return events

                remaining = deadline - time.monotonic()
                if remaining <= 0:
                    raise RpcTimeoutError(
                        f"Timed out waiting for agent_end. Stderr: {self.stderr}"
                    )
                self._event_condition.wait(remaining)

    def _request(self, command_type: str, **payload: JsonValue) -> JsonObject:
        process = self._require_process()
        request_id = self._next_request_id()
        envelope: JsonObject = {"id": request_id, "type": command_type}
        for key, value in payload.items():
            if value is not None:
                envelope[key] = value

        response_queue: queue.Queue[JsonObject | BaseException] = queue.Queue(maxsize=1)
        with self._state_lock:
            self._pending[request_id] = _PendingRequest(
                command=command_type, response_queue=response_queue
            )

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass a larger timeout to wait_for_agent_end for long-running prompts
  2. Check client.stderr for signs the server is stuck (pending tool calls, retries)
  3. Poll asynchronously instead of blocking: use event listeners and a longer supervising deadline
  4. If the server is genuinely hung, abort/stop the prompt and restart the client

Example fix

// before
events = client.wait_for_agent_end()  # default 60s
// after
events = client.wait_for_agent_end(timeout=600)  # long agent runs
Defensive patterns

Strategy: try-catch

Validate before calling

timeout = max(600, expected_run_seconds * 2)  # size timeout to workload

Try / catch

try:
    events = client.wait_for_agent_end(timeout=600)
except RpcTimeoutError as exc:
    log.error("agent run exceeded deadline; stderr=%s", client.stderr)
    client.abort()  # stop the hung run before retrying

Prevention

When it happens

Trigger: Calling wait_for_agent_end(timeout=T) where the agent run legitimately takes longer than T, or the server is stuck (LLM call hanging, tool awaiting input, deadlock in host-tool dispatch).

Common situations: Slow model responses or long tool executions exceeding the default 60s; passing timeout=None-intent but getting default; server hung on a host-tool that never responds.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/01d5d74c790123dc. Report an issue: GitHub.