can1357/oh-my-pi · error · RpcError

Async error history limit was exceeded while waiting for age

Error message

Async error history limit was exceeded while waiting for agent_end. Increase max_event_history if your host needs to retain more background failures.

What it means

Same eviction guard as the event-history error but for the background async-error ring buffer: while waiting for agent_end, the waiter's starting async-error index was already evicted (start_async_error_index < self._async_errors.offset), so earlier background failures can no longer be surfaced reliably.

Source

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

        self,
        start_index: int,
        start_async_error_index: int,
        timeout: float | None = None,
    ) -> tuple[RpcAgentEvent, ...]:
        deadline = time.monotonic() + (timeout if timeout is not None else 60.0)
        with self._event_condition:
            while True:
                if self._closed_error is not None:
                    raise RpcProcessExitError(str(self._closed_error))

                if start_index < self._events.offset:
                    raise RpcError(
                        "Event history limit was exceeded while waiting for agent_end. "
                        "Increase max_event_history to retain more streamed events."
                    )

                if start_async_error_index < self._async_errors.offset:
                    raise RpcError(
                        "Async error history limit was exceeded while waiting for agent_end. "
                        "Increase max_event_history if your host needs to retain more background failures."
                    )

                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
                    )

View on GitHub (pinned to 9690622007)

Solutions

  1. Increase max_event_history so the async-error buffer grows accordingly
  2. Drain/snapshot async errors between runs instead of letting them accumulate beyond the buffer
  3. Fix or disable the repeatedly failing background tool/extension generating the error flood
  4. Check async errors promptly via the client's async-error API rather than only at agent_end

Example fix

// before
client = make_client(max_event_history=128)  # error ring evicts on busy hosts
// after
client = make_client(max_event_history=10_000)
Defensive patterns

Strategy: validation

Validate before calling

if start_async_error_index < client.async_errors_offset():
    raise RuntimeError("async error history evicted; raise max_event_history")

Try / catch

try:
    client.wait_for_agent_end()
except RpcError as exc:
    if "Async error history limit" in str(exc):
        log.warning("background failures lost; increase max_event_history")
    else:
        raise

Prevention

When it happens

Trigger: More than max_event_history worth of async errors accumulated between capturing the start index and the agent_end wait (default error history limit is 128); hosts that generate many background tool failures during long runs.

Common situations: Long-lived sessions where background tasks (extensions, host tools) repeatedly fail; reusing one client across many prompts without inspecting async errors; low error-history limits on busy hosts.

Related errors


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