666ghj/MiroFish · error · RuntimeError

Zep batch {batch_id} item cursor did not advance

Error message

Zep batch {batch_id} item cursor did not advance

What it means

Raised inside GraphBuilder._list_batch_items while paginating Zep batch items with client.batch.list_items(limit=100, cursor=...). The loop terminates when next_cursor is None; if the API ever returns a cursor equal to the current one or one already visited (seen_cursors), it raises RuntimeError to prevent an infinite pagination loop. This indicates a server-side pagination anomaly or an SDK/API version mismatch rather than a problem with the submitted data.

Source

Thrown at backend/app/services/graph_builder.py:600

    def _list_batch_items(self, batch_id: str) -> List[Any]:
        items: List[Any] = []
        cursor: int | None = None
        seen_cursors: set[int] = set()
        while True:
            page = call_zep_read_with_retry(
                lambda: self.client.batch.list_items(
                    batch_id=batch_id,
                    limit=100,
                    cursor=cursor,
                ),
                operation_name=f"list batch items {batch_id}",
            )
            items.extend(getattr(page, "items", None) or [])
            next_cursor = getattr(page, "next_cursor", None)
            if next_cursor is None:
                break
            if next_cursor == cursor or next_cursor in seen_cursors:
                raise RuntimeError(f"Zep batch {batch_id} item cursor did not advance")
            seen_cursors.add(next_cursor)
            cursor = next_cursor
        return items

    def _reconcile_batch_item_count(
        self,
        batch_id: str,
        expected_item_count: int,
        *,
        max_attempts: int = 3,
    ) -> List[Any]:
        """Allow a short propagation window after an ambiguous add reply."""

        items: List[Any] = []
        for attempt in range(1, max_attempts + 1):
            items = self._list_batch_items(batch_id)
            if len(items) >= expected_item_count:
                return items

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Retry the whole read after a short wait (30-60s) — transient cursor instability right after batch completion usually resolves.
  2. Check the zep-cloud SDK version against Zep's current docs and upgrade if it is behind; cursor semantics changed across versions.
  3. If persistent, capture batch_id, page cursors and open a Zep support ticket — a never-advancing cursor is a service defect.
  4. As a defensive workaround in your own fork, re-issue list_items from scratch instead of trusting the repeated cursor.

Example fix

// before
items = self._list_batch_items(batch_id)
# after
for attempt in range(3):
    try:
        items = self._list_batch_items(batch_id)
        break
    except RuntimeError as e:
        if 'cursor did not advance' not in str(e) or attempt == 2:
            raise
        time.sleep(30)
Defensive patterns

Strategy: retry

Try / catch

for attempt in range(3):
    try:
        items = builder._list_batch_items(batch_id)
        break
    except RuntimeError as e:
        if 'cursor did not advance' not in str(e):
            raise
        if attempt == 2:
            raise
        time.sleep(30)  # give Zep's cursor time to stabilize

Prevention

When it happens

Trigger: Calling _list_batch_items on a batch with more than 100 items (multiple pages), where Zep returns a next_cursor that repeats a previously seen value. Can also happen if the batch's items are still being written and list_items returns an unstable cursor, or when a pinned zep-cloud SDK version speaks an older cursor contract than the server.

Common situations: Large batches (hundreds/thousands of items) read immediately after batch completion; Zep service-side pagination regressions; upgrading or downgrading the zep-cloud SDK without regenerating cursor handling; rarely, clock/inconsistency windows during eventual consistency.

Related errors


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