oven-sh/bun · error

Failed to count completed issues: ${error}

Error message

Failed to count completed issues: ${error}

What it means

Thrown by countCompletedIssues() when the `gh issue list --state closed --search "closed:>=<date> reason:completed" --limit 1000 --json ...` invocation fails. It wraps the gh CLI error, so the real cause (query syntax, auth, rate limit, repo context) is in the appended message.

Source

Thrown at scripts/github-metrics.ts:54

  }
}

/**
 * Count issues closed as completed since a given date
 */
async function countCompletedIssues(sinceDate: string): Promise<{ count: number; issues: number[] }> {
  try {
    const result =
      (await $`gh issue list --state closed --search "closed:>=${sinceDate} reason:completed" --limit 1000 --json number,closedAt,stateReason`.json()) as Issue[];

    const completedIssues = result.filter(issue => issue.stateReason === "COMPLETED");

    return {
      count: completedIssues.length,
      issues: completedIssues.map(issue => issue.number),
    };
  } catch (error) {
    throw new Error(`Failed to count completed issues: ${error}`);
  }
}

/**
 * Get positive reactions for an issue (👍, ❤️, 🎉, 🚀)
 */
async function getIssueReactions(issueNumber: number): Promise<number> {
  try {
    const reactions = (await $`gh api "repos/oven-sh/bun/issues/${issueNumber}/reactions"`.json()) as Reaction[];
    return reactions.filter(r => ["+1", "heart", "hooray", "rocket"].includes(r.content)).length;
  } catch {
    return 0;
  }
}

/**
 * Get positive reactions for all comments on an issue
 */

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Run the exact gh command manually to see the raw error: `gh issue list --state closed --search 'closed:>=2026-01-01 reason:completed' --limit 1000 --json number`
  2. Normalize sinceDate to YYYY-MM-DD before calling
  3. Run `gh auth status`; export GH_TOKEN or set GH_REPO=oven-sh/bun
  4. Retry after the rate-limit window if gh reports a secondary rate limit

Example fix

// before
const { count, issues } = await countCompletedIssues(sinceDate);

// after
const since = new Date(sinceDate).toISOString().slice(0, 10);
if (!/^\d{4}-\d{2}-\d{2}$/.test(since)) throw new Error(`bad sinceDate: ${sinceDate}`);
const { count, issues } = await countCompletedIssues(since);
Defensive patterns

Strategy: retry

Validate before calling

// gh search qualifiers need a plain YYYY-MM-DD date
if (!/^\d{4}-\d{2}-\d{2}$/.test(sinceDate)) {
  throw new Error(`sinceDate must be YYYY-MM-DD, got: ${sinceDate}`);
}
await $`gh auth status`.quiet(); // fail fast on auth problems

Try / catch

let result;
for (let attempt = 0; attempt < 3; attempt++) {
  try {
    result = await countCompletedIssues(sinceDate);
    break;
  } catch (error) {
    if (/rate limit/i.test(String(error)) && attempt < 2) continue;
    throw error;
  }
}

Prevention

When it happens

Trigger: sinceDate not in the YYYY-MM-DD form gh's search qualifier expects; gh unauthenticated or its token expired; secondary rate limit from repeated --limit 1000 queries; running outside a git checkout without GH_REPO set.

Common situations: Passing an ISO timestamp or Date object string instead of a plain date; CI where GH_TOKEN isn't in env; running the script in a directory that isn't the bun repo so gh can't infer oven-sh/bun.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/98b6b36b791058c9. Report an issue: GitHub.