666ghj/MiroFish · error · RuntimeError

batch item cursor did not advance

Error message

batch item cursor did not advance

What it means

Raised by _list_batch_items in backend/scripts/validate_zep_cloud_integration.py when client.batch.list_items returns a next_cursor equal to the cursor used for the current page — meaning pagination would fetch the same page forever. Note this guard only compares next_cursor == cursor (an int cursor with None start), not a full seen-set. It is a RuntimeError raised mid-pagination.

Source

Thrown at backend/scripts/validate_zep_cloud_integration.py:313

        if getattr(episode, "processed", False):
            return episode
        time.sleep(3)
    raise TimeoutError(f"episode {episode_uuid} did not finish within {timeout}s")


def _list_batch_items(client: Any, batch_id: str, page_size: int = 3) -> tuple[list[Any], int]:
    items: list[Any] = []
    cursor: int | None = None
    pages = 0
    while True:
        response = client.batch.list_items(batch_id=batch_id, limit=page_size, cursor=cursor)
        pages += 1
        items.extend(response.items or [])
        next_cursor = response.next_cursor
        if next_cursor is None:
            return items, pages
        if next_cursor == cursor:
            raise RuntimeError("batch item cursor did not advance")
        cursor = next_cursor


def _raw_pages(api_call: Any, graph_id: str, page_size: int = 2) -> tuple[list[Any], int]:
    items: list[Any] = []
    cursor: str | None = None
    pages = 0
    seen: set[str] = set()
    while True:
        kwargs: dict[str, Any] = {"limit": page_size}
        if cursor:
            kwargs["cursor"] = cursor
        response = api_call(graph_id, **kwargs)
        pages += 1
        items.extend(list(response.data or []))
        next_cursor = response.headers.get("zep-next-cursor")
        if not next_cursor:
            return items, pages

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Retry the listing after a short wait — transient repetition right after batch.process usually resolves once the batch settles.
  2. Upgrade the zep-cloud package to the latest release.
  3. If reproducible, capture batch_id and both cursor values and report to Zep support; use the console batch view to inspect items meanwhile.
Defensive patterns

Strategy: retry

Try / catch

for attempt in range(3):
    try:
        items, pages = _list_batch_items(client, batch_id, page_size=3)
        break
    except RuntimeError as e:
        if "cursor did not advance" not in str(e) or attempt == 2:
            raise
        time.sleep(5)

Prevention

When it happens

Trigger: Listing a batch's items when the API repeats the same cursor — a batch still settling right after client.batch.process, a server-side cursor bug, or an SDK version mis-reading next_cursor.

Common situations: Polling list_items immediately after process() while the backend still mutates the listing; zep-cloud SDK upgrade changing cursor semantics; rare Zep Cloud API regression.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/b5b7aa710ea1ef35. Report an issue: GitHub.