auto-close-duplicates.ts reads only the first 30 comments and 30 reactions, silently ignoring objections on busy issues

Status Open
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Jul 23, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

scripts/auto-close-duplicates.ts paginates the issues list, but its two other list reads use GitHub's default page size of 30 and never follow pagination:

  • comments: githubRequest(/repos/.../issues/${issue.number}/comments) (line 156) — first 30 comments only
  • reactions: githubRequest(/repos/.../issues/comments/${id}/reactions) (line 220) — first 30 reactions only

sweep.ts in the same directory passes per_page=100 on every list call, so this looks like an oversight rather than a choice.

Consequences

  1. A 👎 beyond the first 30 reactions is silently ignored. The anti-close protection reads only the first page, so on exactly the high-engagement issues the protection is for, it degrades: a dupe notice with 32 👍/❤️ followed by the author's 👎 auto-closes anyway. Real dupe notices are already near the cap — the notice on #44252 has 23 👎, #59033 has 20. This also undercuts #79146 / PR #79151: counting any user's 👎 doesn't help if that 👎 is on page 2.
  1. Human replies after a dupe notice at comment position 30 are invisible. The commentsAfterDupe activity check sees only the first 30 comments, so when the dupe notice is the 30th comment and people object afterwards, the issue closes despite the objections. Notices deep in a thread are a supported path: backfill-duplicate-comments.ts dispatches the dedupe workflow onto old issues that already have long comment threads.
  1. (fail-open) A dupe notice past position 30 is never seen at all, so those issues are silently exempt from auto-close — inconsistent with the intent, though harmless to reporters.

Repro

Mock-fetch harness emulating GitHub pagination semantics (default 30 without per_page), three fixture issues:

  • #101 — dupe notice with 35 reactions, author's -1 at position 33
  • #102 — dupe notice as comment 30 of 35, five human objections after it
  • #103 — clean candidate (old notice, no objections)

Current script: closed: [101, 102, 103] — two wrongful closes.
With pagination (per_page=100 + follow pages): closed: [103].

Fix

Add a small githubRequestAllPages helper and use it for both reads. PR incoming.

View original on GitHub ↗

3 Comments

bcherny collaborator · 1 month ago

Reproduced. Running the current script against a mock GitHub API that faithfully emulates pagination (default page size 30 when per_page isn't specified), with the three fixture issues described here:

  • unmodified script: closes all three — on the busy issue it reports the duplicate-notice comment as having 30 reactions (the author's 👎 at position 33 is never fetched), and on the long thread it sees only the first 30 comments, so the five objections posted after the notice are invisible to the activity check;
  • same script with both reads paginated: closes only the clean candidate.

So both wrongful-close paths are real, and the third consequence (a notice past comment position 30 is never seen at all, exempting the issue from auto-close) follows from the same reads. The comments and reactions fetches indeed use the API's default page size and never follow subsequent pages, while the issues listing in the same script paginates properly — consistent with an oversight rather than a deliberate cap.

Marking as reproduced. A pagination helper applied to both reads (as proposed) fixes all three behaviors.

🤖 Generated with Claude Code

serhiileniv · 1 month ago

Thanks for the repro. The fix is already open as #80508 — same approach: a githubRequestAllPages helper (per_page=100, follows until a short page, same 20-page cap as the existing issues loop) on both the comments and reactions reads. Still mergeable, no conflicts.

marcindulak · 18 days ago

For your information: the label reproduced on this issue does not prevent it from becoming stale and eventually auto-closed. See https://github.com/anthropics/claude-code/issues/87647 for details, and consider upvoting that for visibility.

About the duplicate issues, there is another flaw in handling them https://github.com/anthropics/claude-code/issues/19267.