DEV Community

FirstDollarProject
FirstDollarProject

Posted on

The 100-Comment Blind Spot: Fixing a Bounty Checker That Looked Backward

Summer Bug Smash: Clear the Lineup 🐛🛹

This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry.

Project Overview

Bounty Reality Check is a free screening tool for public GitHub issues and pull requests. It checks whether the item is open, whether the repository is active, how recently it moved, whether a concrete reward is visible, and whether the discussion contains settlement language such as “bounty paid,” “winner selected,” or “submissions closed.”

The project began on August 23, 2026 as part of a zero-upfront-cost experiment to earn one new dollar by first helping other people avoid stale bounties.

Bug Fix or Performance Improvement

The initial version requested GitHub issue comments like this:

githubFetch(
  `/repos/${owner}/${repo}/issues/${number}/comments?per_page=100`,
)
Enter fullscreen mode Exit fullscreen mode

That looks reasonable until an issue has more than 100 comments. GitHub paginates issue comments in chronological order, so the request returns the oldest 100 comments.

That was exactly backward for this product. A bounty usually starts with requirements and claimant messages. Evidence that it was paid, awarded, or closed is much more likely to appear near the end of the discussion. On a 347-comment issue, the checker would inspect comments 1–100 and silently ignore comments 101–347.

The result could be worse than an ordinary UI error: the app could label a settled bounty “likely live” and encourage someone to waste hours on unpaid work.

Code

I added a small, deterministic page calculation:

function latestCommentPage(commentCount: number) {
  return Math.max(1, Math.ceil(commentCount / 100));
}
Enter fullscreen mode Exit fullscreen mode

The issue metadata already includes the total comment count. The checker now fetches the repository and issue first, then requests the final comment page:

const [repoResult, issueResult] = await Promise.all([
  githubFetch(`/repos/${parsed.owner}/${parsed.repo}`),
  githubFetch(`/repos/${parsed.owner}/${parsed.repo}/issues/${parsed.number}`),
]);

const commentsResult = await githubFetch(
  `/repos/${parsed.owner}/${parsed.repo}/issues/${parsed.number}/comments` +
  `?per_page=100&page=${latestCommentPage(issueResult.data.comments ?? 0)}`,
);
Enter fullscreen mode Exit fullscreen mode

The evidence panel now tells the truth about the coverage:

const totalComments = issue.comments ?? comments.length;

const detail = totalComments > 100
  ? 'The newest 100 comments were scanned.'
  : 'All visible comments were included in the scan.';
Enter fullscreen mode Exit fullscreen mode

My Improvements

The key decision was not to fetch every page. Doing that would improve completeness but would also turn one user action into an unbounded number of unauthenticated GitHub API requests. That would make the app slower and exhaust its public rate limit much faster.

Fetching the final page preserves the original ceiling of one comment request while moving the scan to the part of the conversation with the highest settlement value. For 0–100 comments it still scans the complete discussion. For 101 or more, it clearly discloses that it scanned the newest 100.

I verified the fix in three ways:

  • page selection is bounded at 1 for empty and short discussions;
  • counts of 101, 200, and 201 select pages 2, 2, and 3 respectively;
  • the production build completes successfully with the new two-stage request flow.

This is still a screening tool, not a payment guarantee. The fix makes its limited evidence more relevant and its disclosure more accurate.

Disclosure: this project and write-up were produced with an AI coding agent under my direction. I reviewed and authorized the product decisions, public identity, and submission.

Top comments (0)