How we closed 1,500 GitHub issues in one month

Millions of developers use Next.js, and the issue tracker is one of the main ways we learn where they run into problems. It receives an average of 36 new reports each week.

Coding agents have made it easier to file detailed reports, which is great, but it also means a much higher volume of issues to review. For each one, we may need to reproduce the bug, test it across Next.js versions, and search years of pull requests and commits before we can decide what should happen to the report.

The backlog peaked at 3,109 open reports in January 2025. By August 10, 2026, it still had 2,244. Fixed bugs, duplicates, and reports about unsupported versions were burying current regressions. We wanted to close those reports without losing the older issues that still mattered.

Roughly three weeks later, we’d closed 1,462 issues across the repository and brought the backlog below 1,000, even as 218 new reports arrived. That includes some issues maintainers closed outside this review. Here’s the history since 2017:

Open issues in vercel/next.js

3,0002,0001,00003,109 peak2,244995201720212025Sep 4

The selected view begins in 2017. Open issues in vercel/next.js rose to a peak of 3,109 in 2025, then fell from 2,244 on August 10 to 995 on September 4, 2026.

To work through that many issues, we built an agent to research the backlog. Maintainers used its results to close issues with confidence. Keep reading to learn how we did it.

Auto-closing stale issues

We’d already tried using inactivity as a signal. In January 2025, with the backlog at its peak of 3,109 issues, we added a workflow that marked an issue stale after two years without activity (later 18 months) and closed it after a grace period. By August 10, 2026, it had helped bring the backlog down to 2,244.

But inactivity turned out to be a poor stand-in for relevance. An old issue might be fixed, a duplicate, expected behavior, or about something we no longer support. It might also be a real bug that nobody had revisited. A timestamp can’t tell those cases apart, so we closed some reports we should have kept. Getting those calls right meant researching the whole backlog.

Using AI to review issues

Reviewing an issue manually means reading the conversation and relevant code, checking whether linked fixes landed, and trying the reproduction on current releases. Coding agents are well suited to this work. To investigate an issue, they need an environment where they can run the code. For that, we used eve, Vercel’s open-source agent framework. It provides persistent sessions, scheduled runs, and structured outputs, and it can run code on isolated infrastructure like Vercel Sandbox.

On eve, we built closability, a research agent that judges whether an issue can be closed. It runs an investigation in a fresh sandbox with the Next.js repository, Node.js, Playwright, and Chromium, where it:

  1. Reads the GitHub conversation and checks the supported versions.
  2. Searches related issues, pull requests, commits, releases, and documentation.
  3. When needed, tries to reproduce the bug on its reported version, the latest stable release, and canary.
  4. Looks for evidence that contradicts its initial conclusion.

A finished investigation returns structured data. Here’s an example:

{
  "assessment": {
    "closeConfidence": 86,
    "primaryReason": "fixed",
    "summary": "The reported crash was fixed and no longer reproduces on supported releases.",
    "evidence": [
      "PR #71234 merged in Next.js 15.1.4",
      "PR #70001 closed; superseded by merged PR #71234",
      "No longer reproduces on 16.3.0-canary.92"
    ],
    "references": [
      {
        "kind": "pull_request",
        "label": "Fix merged in 15.1.4",
        "url": "
      }
    ]
  }
}

There is no pass or fail signal for whether an issue should close, so closability has to weigh incomplete and sometimes conflicting evidence. We kept its confidence score conservative. A failed reproduction alone is not enough to recommend closing, and a high score requires strong current evidence with nothing credible against it.

We made the agent read-only outside its sandbox. It can research an issue, but it cannot act on its conclusions by commenting, closing an issue, pushing code, or deploying anything. To protect against prompt injection, we also configured it to ignore instructions it finds in issue text or repository content.

Clearing the backlog

We ran closability against the full backlog on GPT-5.6 Luna, with reasoning effort set to max. Investigations took an average of 30 minutes, so we gradually raised concurrency until 200 eve sessions were running at once.

The agent put its results into the Close Queue for us to review. We read the evidence behind every result and kept working through the queue over the following weeks. By September 4, 1,462 issues had been closed across the repository, including some outside this review. Most reviews came down to reading the summary and checking the sources the agent had already gathered.

The agent assigned each closed issue a primary reason. Here’s how the issues were closed:

Reason Issues Share
Already fixed 543 37%
Duplicate 278 19%
Expected behavior 237 16%
No longer reproducible 89 6%
Unsupported or obsolete 66 5%
Other 249 17%
Total 1,462 100%

Before the review, we added a GitHub Action that lets people reopen an issue if closing it turned out to be the wrong call. Whenever a maintainer closes an eligible issue, the Action posts the following comment:

github-actions bot commented

This issue was closed by a maintainer. If you think it was closed by mistake, you can request that it be reopened within the next 14 days.

Reply with Reopen: and explain why the issue is still relevant. If you opened this issue or commented before it was closed, the issue will be reopened automatically.

After 14 days, please open a new issue with up-to-date details and a reproduction, when applicable.

The reopening window gave us a way to check the results. Here’s where the closed issues stand:

remained closed
99.8%

closed
1,459

reopened
3

As of September 4, 2026

These numbers suggest we got most of the decisions right.

The Maintainer Agent

The closability agent is one of several independent eve agents that make up the “Maintainer Agent.” Other agents reproduce issues, verify them on canary, bisect the changes that introduced or fixed them, create end-to-end tests, and prepare fixes.

The code is organized into a directory for each agent:

├── closability/
│   ├── agent/
│   │   ├── agent.ts
│   │   ├── instructions.ts
│   │   ├── channels/
│   │   ├── hooks/
│   │   ├── sandbox/
│   │   ├── schedules/
│   │   └── tools/
│   └── package.json
├── reproduction/
├── verification/
├── e2e_test/
├── fix/
└── ...

We also hooked up the Maintainer Agent to a Next.js dashboard. It shows issues, backlog trends, and research results, and maintainers use it to review the Close Queue and start investigations manually. When an investigation needs multiple agents, the app decides which one runs next, passes results along, and records what happened.

The dashboard includes a chat agent for questions about a specific issue or pull request. From an issue, maintainers can ask it to inspect the source code or start an investigation. The Maintainer Agent sends high-priority findings and a daily recap to Slack.

Keeping the backlog useful

The one-time pass cleared much of the old backlog, but new issues keep coming in. So every Monday, closability researches up to 100 open issues with no activity for at least 30 days, starting with the issues it has never reviewed. If an issue gets new activity, we discard the saved research.

Recently, we decided to let the agents close the clearest cases without waiting for a maintainer:

  1. The closability agent reviews the issue first.
  2. For scores of 80 or higher, a second agent looks for evidence that the issue should stay open.
  3. If both agents recommend closing it, the second agent chooses the closing reason and writes the comment. A separate GitHub Action posts the comment and closes the issue.

We’re starting with up to 25 issues a week. People can still reopen an issue if we get the call wrong. This automation only closes issues, and every code change still goes through human review before it is merged into Next.js.

As Next.js keeps growing and AI speeds up open source development, maintainers have more issues and pull requests to review. We plan to continue automating more of this work so we can manage the volume without missing feedback and contributions from the community.

Feedback and Community

Share your feedback and help shape the future of Next.js:

Similar Posts

Leave a Reply