Skip to content

GraphQl: Fix duplicated items in descending pagination - #352

Merged
iLLiCiTiT merged 2 commits into
developfrom
bugfix/graphql-descending-pagination-duplicates
Sep 14, 2026
Merged

GraphQl: Fix duplicated items in descending pagination#352
iLLiCiTiT merged 2 commits into
developfrom
bugfix/graphql-descending-pagination-duplicates

Conversation

@BigRoy

@BigRoy BigRoy commented Sep 12, 2026

Copy link
Copy Markdown
Member

Bug

Querying GraphQl in descending order (order=SortOrder.descending, or get_events(last=...)) returns the same items many times once more than one page (300 items) is needed.

On a local server, get_events(order=SortOrder.descending, limit=900) returned 900 events of which only 302 were unique.

Cause

For descending order the next page was requested with before: <pageInfo.startCursor>.

AYON server returns the edges of a page queried with last: N ordered from the newest item, and startCursor is the cursor of the first edge, so it points to the newest item of the page. Requesting before that item returns the same page again shifted by one item:

last: 3                    -> [66964] [66963] [66962]   startCursor=[66964] endCursor=[66962]
last: 3, before: [66964]   -> [66963] [66962] [66961]   <- 2 of 3 items are duplicates
last: 3, before: [66962]   -> [66961] [66960] [66959]   <- correct continuation

Fix

Always continue from endCursor (the cursor of the last received edge) — after: for ascending, before: for descending — and query endCursor in pageInfo for both orders. As a side effect descending results are now returned in consistent descending order instead of page-shuffled.

Reproduce

Requires a server with more than 300 events.

import ayon_api
from ayon_api.utils import SortOrder

events = list(ayon_api.get_events(
    order=SortOrder.descending, limit=900, include_logs=True
))
print(len(events), len({event["id"] for event in events}))
# develop:   900 302
# this PR:   900 900

Testing notes

  • Run the snippet above (or get_events(last=900)) and compare total vs. unique ids; also check createdAt is descending.
  • Ascending queries are unaffected (endCursor was already used), e.g. get_folders on a project with more than 300 folders still returns all folders.
  • tests/test_graphql_descending_pagination.py reproduces it against an in-memory fake server (no AYON server needed).

🤖 Generated with Claude Code

Descending pagination continued from 'startCursor'. Server returns edges
of a page queried with 'last' from the newest item, so 'startCursor'
points to the newest item of the page and the next page overlapped the
previous one except for one item. Continue from 'endCursor' for both
orders.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@BigRoy
BigRoy requested a review from iLLiCiTiT September 13, 2026 20:10
@BigRoy
BigRoy marked this pull request as ready for review September 13, 2026 20:10
@BigRoy BigRoy added the type: bug Something isn't working label Sep 13, 2026
@BigRoy
BigRoy requested a lite review from Copilot September 13, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The fake server always raises an unbalanced-query error, so the regression test cannot run.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes duplicate results in descending GraphQL pagination and adds regression-test infrastructure.

Changes:

  • Uses endCursor for descending pagination.
  • Adds an in-memory GraphQL fake server.
  • Adds regression coverage for ordering and duplicate-free results.
File summaries
File Summary
tests/test_graphql_descending_pagination.py Adds descending pagination regression coverage.
tests/graphql_fake_server.py Adds fake GraphQL server support; critical parser validation issue prevents tests from running.
ayon_api/graphql.py Updates pagination to use endCursor.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +101 to +102
if stack:
raise ValueError("Unbalanced query")
@iLLiCiTiT
iLLiCiTiT merged commit 0262af1 into develop Sep 14, 2026
3 checks passed
@iLLiCiTiT
iLLiCiTiT deleted the bugfix/graphql-descending-pagination-duplicates branch September 14, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants