{"record":{"id":"ad4fd669fddcbe37","repo":"666ghj/MiroFish","slug":"artifact-cursor-did-not-advance","errorCode":null,"errorMessage":"artifact cursor did not advance","messagePattern":"artifact cursor did not advance","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"backend/scripts/validate_zep_cloud_integration.py","lineNumber":333,"sourceCode":"\n\ndef _raw_pages(api_call: Any, graph_id: str, page_size: int = 2) -> tuple[list[Any], int]:\n    items: list[Any] = []\n    cursor: str | None = None\n    pages = 0\n    seen: set[str] = set()\n    while True:\n        kwargs: dict[str, Any] = {\"limit\": page_size}\n        if cursor:\n            kwargs[\"cursor\"] = cursor\n        response = api_call(graph_id, **kwargs)\n        pages += 1\n        items.extend(list(response.data or []))\n        next_cursor = response.headers.get(\"zep-next-cursor\")\n        if not next_cursor:\n            return items, pages\n        if next_cursor == cursor or next_cursor in seen:\n            raise RuntimeError(\"artifact cursor did not advance\")\n        seen.add(next_cursor)\n        cursor = next_cursor\n\n\ndef _edge_view(edge: Any, node_names: dict[str, str]) -> dict[str, Any]:\n    return {\n        \"uuid\": _uuid(edge),\n        \"name\": edge.name,\n        \"fact\": edge.fact,\n        \"source\": node_names.get(edge.source_node_uuid, edge.source_node_uuid),\n        \"target\": node_names.get(edge.target_node_uuid, edge.target_node_uuid),\n        \"created_at\": edge.created_at,\n        \"valid_at\": edge.valid_at,\n        \"invalid_at\": edge.invalid_at,\n        \"expired_at\": edge.expired_at,\n        \"attributes\": edge.attributes or {},\n    }\n","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/scripts/validate_zep_cloud_integration.py#L315-L351","documentation":"Raised by _raw_pages in backend/scripts/validate_zep_cloud_integration.py when the zep-next-cursor response header equals the current cursor or reappears in the seen set. _raw_pages deliberately walks the with_raw_response API (response.data plus response.headers) to cross-check the production fetch_all_* helpers, so this error means the raw cursor traversal itself would not terminate. It is a RuntimeError.","triggerScenarios":"Paginating graph.node/edge.with_raw_response.get_by_graph_id with limit=page_size when the server (or an intermediate proxy that rewrites headers) returns a duplicated zep-next-cursor value across pages.","commonSituations":"A corporate proxy or gateway normalizing/duplicating response headers; zep-cloud SDK version parsing headers differently; server-side pagination regression on Zep Cloud.","solutions":["Retry the run — transient header anomalies are usually not stable.","Upgrade zep-cloud to the latest version.","If a proxy sits between the script and Zep Cloud, bypass it and compare results.","Report persistent cases to Zep support with graph_id and the offending cursor values."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    items, pages = _raw_pages(api_call, graph_id, page_size=2)\nexcept RuntimeError as e:\n    if \"artifact cursor did not advance\" in str(e):\n        time.sleep(5)\n        items, pages = _raw_pages(api_call, graph_id, page_size=2)\n    else:\n        raise","preventionTips":["Run validation from a network path without header-rewriting proxies.","Keep zep-cloud upgraded; zep-next-cursor header parsing has changed across versions.","Log the raw header values when pagination stalls to speed up vendor reports."],"tags":["zep","pagination","http-headers","infinite-loop-guard","validation-script"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}