can1357/oh-my-pi · warning · RpcTimeoutError

Timed out waiting for an extension UI request

Error message

Timed out waiting for an extension UI request

What it means

next_ui_request() blocks on an internal queue of pending extension UI requests (questions/prompts the server wants the host UI to render). If no request arrives before the optional timeout expires, queue.Empty is caught and re-raised as RpcTimeoutError. It signals 'no extension UI interaction was requested in time', not a protocol failure.

Source

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

            if request.method == "input":
                if input_value is not None:
                    self.send_ui_value(request.id, input_value)
                else:
                    self.cancel_ui_request(request.id)
                return
            if request.method == "editor":
                if editor_value is not None:
                    self.send_ui_value(request.id, editor_value)
                else:
                    self.cancel_ui_request(request.id)

        return self.on_ui_request(handle)

    def next_ui_request(self, timeout: float | None = None) -> ExtensionUiRequest:
        try:
            return self._ui_requests.get(timeout=timeout)
        except queue.Empty as exc:
            raise RpcTimeoutError(
                "Timed out waiting for an extension UI request"
            ) from exc

    def send_ui_value(self, request_id: str, value: str) -> None:
        self._send_notification(
            {"type": "extension_ui_response", "id": request_id, "value": value}
        )

    def send_ui_confirmation(self, request_id: str, confirmed: bool) -> None:
        self._send_notification(
            {"type": "extension_ui_response", "id": request_id, "confirmed": confirmed}
        )

    def cancel_ui_request(self, request_id: str, *, timed_out: bool = False) -> None:
        payload: JsonObject = {
            "type": "extension_ui_response",
            "id": request_id,
            "cancelled": True,

View on GitHub (pinned to 9690622007)

Solutions

  1. Increase or drop the timeout argument (timeout=None waits indefinitely)
  2. Before waiting, confirm the prompt/agent run is actually active and can produce a UI request
  3. Catch RpcTimeoutError and either re-poll or treat the run as complete
  4. Check server-side logs/state to see whether an extension UI request was ever emitted

Example fix

# before
request = client.next_ui_request(timeout=2)  # raises on slow agents

# after
try:
    request = client.next_ui_request(timeout=30)
except RpcTimeoutError:
    request = None  # no UI interaction pending; continue or finish
Defensive patterns

Strategy: try-catch

Validate before calling

# ensure a run is active before waiting for UI requests
state = client.get_state()
ready = state is not None and getattr(state, "active", False)

Try / catch

try:
    request = client.next_ui_request(timeout=30)
except RpcTimeoutError:
    request = None  # no pending UI interaction; proceed or finish

Prevention

When it happens

Trigger: Calling next_ui_request(timeout=N) when the server sends no extension/ui request within N seconds; calling with no timeout on an idle session where the server never issues a UI request.

Common situations: Test harnesses waiting for an agent question that never fires (agent finished or errored earlier); timeouts set too short for slow model responses; polling loop that forgot the session already answered the pending UI request.

Understand the failure class

Related errors


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