Duplicate profiles when paging relationships/profiles without sort - bug or expected?
Walking a segment's or a list's profile relationships with the default cursor gives me the same profiles on more than one page. Adding sort=joined_group_at makes it go away.
To reproduce: add a batch of profiles to a list in one call so they all share a joined_group_at, then page through GET /api/lists/{id}/relationships/profiles with no sort.
On a 51-member segment, no sort:
page[size]=2 gave 54 rows, 3 profiles repeated page[size]=3 gave 57 rows, 6 repeated page[size]=5 gave 61 rows, 10 repeated
The same three walks with sort=joined_group_at gave exactly 51 rows and nothing repeated. Bigger pages are worse - a separate 40-member list came back with 66 rows at page[size]=25.
I think the cursor just isn't tiebroken. Decoded, the default one is next::id::<n>, but the rows come back in join order, so profiles sharing a joined_group_at sit across the page boundary and get sent twice. Pass the sort and the cursor becomes next::created::<timestamp>::id::<n>, which has the tiebreak in it, and every walk I tried after that came back clean.
Someone hit the same thing on the metric timeline endpoint a while back where events shared a timestamp, and the answer there was also to pass an explicit sort.
Could the default cursor be tiebroken? Or if not, could the docs mention that sort=joined_group_at is needed for stable paging here? Nothing on the reference page suggests the default isn't safe.
I haven't seen anything go missing, only duplicates. Though a boundary that repeats rows can presumably skip them too, which would matter if you're using this to diff membership.
