Back arrowAll guides

Why Does a GitHub Stale Bot Close Feature Requests People Still Want?

Pixel art of two glowing green issue nodes connected by a line on a dark green background
Talton Figgins••6 min read

A stale bot closes an issue because nobody left a new comment on it inside a fixed window, and that's the entire check. GitHub's own actions/stale marks an issue stale after 60 days with no update to its updated_at field, then closes it 7 days after that if still nothing changes. Reactions don't reset that clock. The action's documentation never mentions thumbs-up counts, view counts, or how many other issues raise the same request. The only inputs it reads are comments, edits, labels, milestones, and assignees. A feature request with forty 👍 reactions and zero new comments in ten weeks looks, to the bot, indistinguishable from an issue nobody has thought about since the day it was filed.

That's the mechanical answer. The reason it feels wrong is that "still wanted" and "recently commented on" are different things, and the bot only measures the second one. An issue can be exactly as wanted on day 67 as it was on day 1. The people who want it aren't obligated to keep typing "+1" to prove it, and if they do, that comment resets the timer, so the cycle just repeats two months later.

What the default actually checks, and what it ignores

The two defaults worth knowing are days-before-stale: 60 and days-before-close: 7, per the action's README. Inside that window, the only way to stop the clock is a genuine update to the issue, a new comment, an edit, a label change, a milestone, or an assignee. The README's exemption options are exempt-issue-labels, exempt-milestones, and exempt-assignees; there is no exempt-above-N-reactions or anything close to it. Reaction counts, duplicate-report counts, and cross-repo mentions sit entirely outside what the bot can see, by design. It's a lightweight action reading one field on one issue, not a demand-tracking system.

That gap is exactly what people keep filing issues about against the tool itself. An open issue on actions/stale describes the failure mode directly: "issues or pull requests where the reporter is waiting on the response or feedback from the maintainer are closed as 'stale'... this can be extremely frustrating for the user because they continuously waste their time (and clutter the comments) by keeping an issue 'updated', eventually giving up." A similar report on the older probot/stale puts the underlying complaint in one line: "just because the repository maintainer has not answered does not make the issue stale." Both are asking for the same thing the built-in exemptions don't offer, a way to say "this one still matters" that isn't a fresh comment.

The counter-argument, made at length in the widely shared post "GitHub stale bot considered harmful", is that treating an open issue as a problem to be cleaned up is the wrong frame to begin with. Drew DeVault argues an issue tracker doubles as "a place for motivated users to collaborate," not a queue of action items owed a response, and that "there is no shame in having a lot of open issues — if anything, it signals popularity." Whether or not a maintainer agrees with that framing for their own repo, it explains why so many teams end up disabling or heavily configuring the default stale workflow rather than running it as shipped.

The DIY fixes, and where they stop

Three adjustments cover most of what a small team needs, and they're worth doing regardless of anything past that point:

  • Exempt anything triaged. Add exempt-issue-labels: enhancement,accepted,help-wanted (or whatever your accepted-work label is) so the bot only ever ages out issues nobody has looked at, not issues waiting on the maintainer's own backlog.
  • Widen the window before adding it back at all. A days-before-stale of 60 or 90 with a generous days-before-close gives real feature requests more runway than the tool's own numbers assume you want.
  • Check reactions before the job runs. A short actions/github-script step that reads each issue's reaction count via the API and applies the exempt label above some threshold before the stale job executes will keep a heavily-upvoted request from closing on comment silence alone. It's a script you maintain, not a checkbox.

None of that gives you a count. Reactions and duplicate filings tell you a request has resurfaced, but turning "eleven thumbs-up and two duplicate issues" into "thirteen people, in three companies, want this" is manual work. It means reading each reaction's profile, matching duplicate issues by hand, and remembering to check again next month. It scales to one maintainer checking one repo occasionally. It doesn't scale to a team with issues arriving from GitHub, a support inbox, and a Slack channel at the same time, where the same request can be stale-closed on GitHub while it's still alive and active somewhere else the bot never looks.

For that team, we'd point at Modem. Modem watches connected GitHub repos alongside Slack, Discord, and support tools, and instead of measuring one issue's comment timestamp, it counts how many separate people and companies keep raising the same underlying request across all of them, closed issue or not. A request that GitHub's bot auto-closed for silence still shows up as an open, counted topic in Modem if people keep mentioning it elsewhere, with every mention linked back to who raised it. Modem is our product. The comparison rows for the others come from their public docs. But the gap it closes is specific. A stale bot's silence isn't the same fact as nobody wanting the thing, and Modem is built to keep tracking the second fact even after GitHub has acted on the first.

If your repo's real problem is broader than one bot's defaults, duplicate reports piling up, or nobody able to say who actually asked for what, the wider mechanics are in how to triage GitHub issues at scale and can GitHub detect duplicate issues before they pile up.

What to change today

The default actions/stale config closes on silence alone, so the fastest fix is a config change, not a rewrite: label your own backlog as exempt and stop treating 60 days as sacred if that's not how fast your team actually replies. That stops the bot from punishing work you've already accepted. It still won't tell you when a closed issue is being asked for on Slack, Discord, or a support ticket, the exact channels the bot never reads. For that, someone has to be watching more than the one field the bot checks.