---
title: How we closed 1,500 GitHub issues in one month
description: How the Next.js team used an agent to research old reports and work through the issue backlog.
url: "https://nextjs.org/blog/how-we-closed-1500-github-issues"
docs_index: /docs/llms.txt
publishedAt: September 4th 2026
authors:
  - Marcos Hernanz
---



Millions of developers use Next.js, and the [issue tracker](https://github.com/vercel/next.js/issues) 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:

<IssueBacklogChart />

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](https://github.com/vercel/next.js/pull/73488) that marked an issue stale after two years without activity (later [18 months](https://github.com/vercel/next.js/pull/75630)) 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](https://vercel.com/blog/introducing-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](https://vercel.com/docs/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:

```json filename="Example result"
{
  "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": "https://github.com/vercel/next.js/pull/71234"
      }
    ]
  }
}
```

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](https://github.com/vercel/next.js/pull/96947) 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:

<IssueReopenComment />

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

<IssueReopenSummary />

These numbers suggest we got most of the decisions right.

## The Maintainer Agent

The `closability` agent is one of several independent [eve](https://vercel.com/blog/introducing-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:

```text filename="apps/agent/agents"
├── 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](https://github.com/vercel/next.js/blob/canary/.github/workflows/next-maintainer-auto-close.yml) 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:

- [GitHub Discussions](https://github.com/vercel/next.js/discussions)
- [GitHub Issues](https://github.com/vercel/next.js/issues)
- [Discord Community](https://nextjs.org/discord)
