Skip to content

claimIssue bypasses the 3-active-claim limit — unlimited claims via Browse Issues page #857

Description

@namann5

What happened?

The "Claim" button on the Browse Issues page (claimIssue in src/app/actions/issues.ts) does not enforce the 3-active-claims limit, unlike its twin action claimRecommendation in src/app/actions/recommendations.ts.

claimRecommendation enforces the rule with a pre-check + post-commit rollback:

// recommendations.ts:119-127
const { count: preCount } = await service
  .from('recommendations')
  .select('id', { count: 'exact', head: true })
  .eq('user_id', user.id)
  .eq('status', 'claimed')
  .gte('expires_at', now);
if ((preCount ?? 0) >= 3) {
  return err('claim_limit', 'you already have 3 active claims - merge or close them first');
}

claimIssue performs no such count — it only checks that the user hasn't already claimed this specific issue (issues.ts:329-350), then inserts a status: 'claimed' row unconditionally:

// issues.ts:354-367
const { data: inserted } = await service
  .from('recommendations')
  .insert({ ... status: 'claimed', claimed_at: now })
  .select('id').single();

Both paths write to the same recommendations table with status: 'claimed', so a user can claim unlimited distinct issues via the issues page, bypassing the 3-active-claim rule entirely.

Steps to Reproduce

  1. Sign in with a fresh account and install the GitHub App.
  2. Open /issues and click "Claim" on 4+ different issues.
  3. All four claims succeed — the dashboard then shows 4+ active claims.
  4. Attempt to claim a recommended issue from the dashboard: blocked by claim_limit.

Expected Behavior

claimIssue should count the user's active (non-expired, status = 'claimed') recommendations and reject when >= 3, mirroring claimRecommendation. It should also apply the same atomic post-claim verification/rollback so concurrent requests can't slip past the limit.

Where does this occur?

Contributor Dashboard

Environment

Not environment-specific — logic bug reproducible in any deployment.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions