can1357/oh-my-pi · error · RpcError

RPC message pagination ended before the advertised total

Error message

RPC message pagination ended before the advertised total

What it means

After the cursor loop ends (next_cursor became None), the client compares the accumulated message count with the advertised total_messages and raises this RpcError if fewer were received. The server claimed N total messages but stopped paging early, so the transcript would be silently truncated without this check.

Source

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

                while True:
                    page = self.get_messages_page(cursor=cursor, limit=256)
                    if (
                        total_messages is not None
                        and page.total_messages != total_messages
                    ):
                        raise RpcError(
                            "RPC message pagination returned an inconsistent total"
                        )
                    total_messages = page.total_messages
                    messages.extend(page.messages)
                    cursor = page.next_cursor
                    if cursor is None:
                        break
                    if cursor in seen_cursors:
                        raise RpcError("RPC message pagination repeated a cursor")
                    seen_cursors.add(cursor)
                if len(messages) != total_messages:
                    raise RpcError(
                        "RPC message pagination ended before the advertised total"
                    )
                return tuple(messages)
            except RpcCommandError as error:
                if error.command != "get_messages_page" or not (
                    error.code in _RPC_MESSAGES_PAGE_FALLBACK_CODES
                    or error.error
                    in (
                        _RPC_MESSAGES_PAGE_BUSY_ERROR,
                        _RPC_MESSAGES_PAGE_STALE_ERROR,
                    )
                ):
                    raise
        payload = self._request("get_messages")
        return parse_agent_messages(cast(JsonValue | None, payload.get("messages")))

    def get_messages_page(
        self, *, cursor: str | None = None, limit: int | None = None

View on GitHub (pinned to 9690622007)

Solutions

  1. Retry the pagination from the start once the session is idle
  2. Upgrade the server; this is usually a server-side pagination defect
  3. Log per-page counts and totals to identify which page lost messages
  4. If compaction is expected, use a server version that reports totals consistent with compacted state

Example fix

# before: trusting a single pass against a mutating session
messages = client.get_all_messages()

# after: reconcile with the current state before paging
client.wait_until_idle()  # or poll state until no active run
messages = client.get_all_messages()
Defensive patterns

Strategy: retry

Validate before calling

first = client.get_messages_page(cursor=None, limit=256)
expected = first.total_messages
# compare later against len(collected); retry if the session is still active

Try / catch

try:
    messages = client.get_all_messages()
except RpcError as e:
    if "ended before the advertised total" in str(e):
        messages = client.get_all_messages()  # one clean re-read after settling
    else:
        raise

Prevention

When it happens

Trigger: Server reports totalMessages=N but the final page's nextCursor becomes None after fewer than N messages were returned — e.g. messages dropped/compacted between pages, a page handler that silently truncates, or duplicated-cursor paths skipped after the seen_cursors guard.

Common situations: Server-side compaction removing messages mid-pagination; server bug returning oversized pages that drop items; mismatch between the total computed at page 1 and what later pages actually contain.

Related errors


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