Skip to content

fix: Stop the paginator when a page cursor repeats - #575

Open
razor-x wants to merge 1 commit into
mainfrom
claude/ruby-sdk-audit-xbhaia-paginator-loop-guard
Open

fix: Stop the paginator when a page cursor repeats#575
razor-x wants to merge 1 commit into
mainfrom
claude/ruby-sdk-audit-xbhaia-paginator-loop-guard

Conversation

@razor-x

@razor-x razor-x commented Sep 1, 2026

Copy link
Copy Markdown
Member

Problem

SDK audit finding M6. Paginator#flatten and #flatten_to_list looped on has_next_page? with no cursor-repeat detection and no page bound. A server regression or proxy-cached page that returns the same next_page_cursor hung flatten forever and grew flatten_to_list until the process ran out of memory. The per-request timeout resets on every page, so nothing else stopped it.

Fix

Ported from seamapi/python#641 and seamapi/php#466: one private walk enumerator yields each page once, remembers the cursors it has used, and stops when a cursor repeats, is nil, or is empty. Both public methods consume it, so the guard cannot drift between them.

Also drops the paginator's unused require_relative "http", which loaded the client circularly.

Tests

New spec/seam_client/paginator_loop_guard_spec.rb (WebMock): a server that pins one cursor yields exactly two pages and two requests for both flatten and flatten_to_list; a page reporting has_next_page: true with no cursor stops after the first page.

Revert-check against main: the repeated-cursor specs never finish and had to be killed by a 60s timeout.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SQW83gyXeUG61RDrHEky97


Generated by Claude Code

flatten and flatten_to_list looped on has_next_page with no memory of the
cursors already used, so a server regression or proxy-cached page that
pinned one cursor hung flatten forever and grew flatten_to_list without
bound. Nothing else halts the loop, since the per-request timeout resets
on every page.

Walk the pages once in a private enumerator shared by both methods,
remembering each cursor and stopping when a cursor repeats, is nil, or is
empty. Also drop the paginator's unused require of http, which loaded the
client circularly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SQW83gyXeUG61RDrHEky97
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants