Issue list: descending priority sort duplicates the boundary issue across pages
Summary
When the issue list is sorted by Priority in descending order (sort=-priority)
and the result spans more than one page, the last issue on a page reappears as the
first issue on the next page — a single issue is shown twice across the page break.
Ascending priority does not reproduce it in the cases tested, and integer/timestamp
sorts (-count, -last_seen, -first_seen) are unaffected.
Reproduction
Create 3 issues in one project with distinct, monotonic count / last_seen so the
priority values are distinct, then page with limit=2:
GET /api/0/organizations/<org>/issues/?limit=2&sort=-priority
-> page 1 = [issue3, issue2]
follow the rel="next" cursor
-> page 2 = [issue2, issue1] # issue2 is duplicatedExpected page 2 = [issue1].
Cause
priority is a computed float annotation:
priority = LOG(10, index.count) + EXTRACT(epoch FROM index.last_seen) / 300000The cursor paginator (AsyncLinkHeaderPagination /
ninja_cursor_pagination) stores the ordering value as the cursor position via
str(value) and filters the next page with priority__lt='<stringified float>'.
For a descending float sort that < boundary does not reliably exclude the row the
position came from, so the boundary issue is returned again. Integer/timestamp
positions are exact, which is why only the float-valued priority sort is affected.
Relevant code: glitchtip/api/pagination.py (_get_position_from_instance, the
cursor.position filter in apaginate_queryset).
Notes
- This is distinct from the count crash fixed in !2471 (merged) (that was a
42803in the X-Hits count query for the same sort). The count fix removed the 500 that was previously masking this duplication, so it is now observable. - The regression test added in !2471 (merged) (
test_priority_sort_paginated_count) intentionally asserts only status +X-Hitsfor priority sorts and does not assert strict cross-page dedup, precisely because of this open bug. A fix here should also tighten that test to assert each issue appears exactly once across pages forpriority/-priority.
Possible directions
- Quantize/round the float position deterministically so the stored position and the DB-side comparison agree on the boundary, or
- Paginate
prioritywith a stable secondary tiebreaker (e.g. issue id) so the boundary comparison is exact.