Skip to content

fix(pagination): follow next cursors through empty pages - #891

Open
sylvesterkaczmarek wants to merge 3 commits into
openai:mainfrom
sylvesterkaczmarek:fix/next-cursor-empty-pages
Open

fix(pagination): follow next cursors through empty pages#891
sylvesterkaczmarek wants to merge 3 commits into
openai:mainfrom
sylvesterkaczmarek:fix/next-cursor-empty-pages

Conversation

@sylvesterkaczmarek

Copy link
Copy Markdown

Summary

Make NextCursorPage pagination follow explicit server-provided next cursors through empty first or intermediate pages.

Previously, both NextCursorPage.GetNextPage() and NextCursorPageAutoPager.Next() stopped solely because the current data array was empty, before consulting has_more or next. Public auto-pagination such as Admin.Organization.Groups.ListAutoPaging could therefore silently miss later results.

GetNextPage() now lets the explicit cursor metadata decide whether another page exists, and the auto-pager loops across empty pages until it either finds data, encounters an error, or reaches a terminal page. Populated-page behavior is unchanged.

Testing

  • regression-first public Groups.ListAutoPaging coverage for empty first and intermediate pages
  • focused pagination regression: passed
  • SKIP_MOCK_TESTS=true go test ./... — passed on Go 1.26.7
  • ./scripts/check-go-mod — all four modules tidy
  • ./scripts/lint — all analyzer passes reported 0 issues
  • Castiron custom-code tests — 51 passed, 1 skipped
  • committed-revision Castiron budget check — passed (759 / 2000 custom lines)
  • git diff --check — passed

Fixes #890.

@sylvesterkaczmarek
sylvesterkaczmarek requested a review from a team as a code owner September 4, 2026 20:58
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T00:30:23.101831Z 348cafa New commits
🔒 Security Review Completed 2026-09-06T00:30:16.615590Z 348cafa New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19f35b11d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return false
}
if r.idx >= len(r.page.Data) {
for {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Stop when empty pages repeat a cursor

When the server, including a custom endpoint, returns an empty page with has_more: true and repeatedly supplies the same non-empty next cursor, this loop never returns from a single Next() call: every GetNextPage() succeeds with another empty page and the loop immediately requests it again. The removed empty-page guard previously bounded this case, whereas the new behavior can hang and issue unbounded HTTP requests when the context has no deadline; track visited cursors, or at least stop on a non-advancing cursor, while continuing through distinct empty pages.

Useful? React with 👍 / 👎.

@sylvesterkaczmarek

Copy link
Copy Markdown
Author

Addressed the repeated-cursor case. The auto-pager now tracks cursors it has already followed and stops before issuing another request when a cursor repeats, while still traversing distinct empty pages. Added a regression with an empty page that returns the same next cursor.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0eddbd65c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/pagination/pagination.go Outdated
idx int
run int
err error
seenCursors map[string]struct{}

@chatgpt-codex-connector chatgpt-codex-connector Bot Sep 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve auto-pager comparability when tracking cursors

When downstream code instantiates this public generic with a comparable item type and compares concrete pager values or uses them as map keys, adding the map field makes NextCursorPageAutoPager[T] non-comparable, so code that compiled against the previous release now fails to compile. Keep the cursor set behind a comparable indirection (for example, a pointer to the map) so cycle detection does not change the exported type's comparability.

AGENTS.md reference: AGENTS.md:L71-L73

Useful? React with 👍 / 👎.

@sylvesterkaczmarek

Copy link
Copy Markdown
Author

Addressed the comparability regression. Cursor tracking now sits behind a pointer to the private map, so NextCursorPageAutoPager[T] remains comparable whenever T is comparable. Added a compile-time regression that compares two NextCursorPageAutoPager[int] values. The local machine still does not have the Go toolchain, so full formatting/tests are left to repository CI; git diff --check passes.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 348cafaeb7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

idx int
run int
err error
seenCursors *map[string]struct{}

@chatgpt-codex-connector chatgpt-codex-connector Bot Sep 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Move the pagination fix into the Castiron generator

This patches Castiron-owned pagination scaffolding only in the generated SDK, so Castiron's canonical output still contains the empty-page defect and future fresh generations or other generated SDKs will continue to emit it; the local repository must also carry this as a permanent custom patch. Fix the shared pagination template and regenerate this file rather than addressing the recurring defect solely in generated output.

AGENTS.md reference: AGENTS.md:L68-L70

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Confirmed. packages/pagination/pagination.go is Castiron-owned, and the canonical pagination template is not present in this repository or in any Castiron repository accessible through this account. The SDK branch therefore cannot honestly claim a generator-complete fix. I’m leaving the current patch and regressions as the concrete reproducer/SDK-side implementation; a durable fix requires the same change in Castiron followed by regeneration. Maintainers, please advise whether you want this PR retained for that port or closed in favor of a generator-side change.

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.

NextCursorPage auto-pagination stops on empty pages with a next cursor

1 participant