Sitelet https://github.com/nodejs/node/issues/42981
Skip to content

Auto closing old stale PRs #42981

Description

@mhdawson

Our backlog of feature requests has gone down from 249 to 87 with the stale feature request automation we put in place. A number of older ones are still open and we did not get too many complaints so I think it was easy enough for people to keep feature requests open that were still active/needed etc. while at the same time closing those that would likely never get addressed.

Looking at our PRs we have 340 open, 117 which are older than 1 year (https://github.com/nodejs/node/pulls?q=is%3Apr+is%3Aopen+created%3A%3C2021-05-05+).

When I look at those, in many cases the last comment is also a long time ago.

My thought is that for a PR 1 year old, which does not have any comments/updates in the last 6 months it's very unlikely that it's ever going to land. The longer it goes, the more likelyhood of conflicts etc. and that the original poster will no longer be around to help get it over the finish line.

Even in some cases where the PR looks like it was ready to land, we need something to kick it to our attention, or to get the originator to remind us its ready to land if they still care.

It's strange that 106 of those old PRs show as updated on Feb 24th, even though I can't see how they were updated when I look at the issues. Ignoring this issue I think it would be resonable to use an approach similar to what we did for feature requests with a different set of criteria.

PRs older than 1 year, no comments in last 5 months -> warn that PR is considered stale and will be closed if there is no comment in the next month
PRs older than 1 year, no comments in last 6 months -> close with appropriate message.

Thoughts?

Activity

  1. added
    tsc-agendaIssues and PRs to discuss during Technical Steering Committee meetings.
    on May 5, 2022
  2. ljharb commented on May 9, 2022

    @ljharb
    SponsorMember

    My experience is that non-humans closing things comes across as hostile (lacking compassion, etc). Using a bot to auto-tag stale issues with a human manually closing them later is fine; using a bot to auto-close them is a problem.

  3. mhdawson commented on May 10, 2022

    @mhdawson
    MemberAuthor

    @ljharb I understand where you are coming from but I think the problem is that a human manually closing them later does not occur. I see issues where people periodically comment "is this still active" a number of times which streches over months or possibly longer. In the node-addon-api repo I've seen the stale autotagging and knowing that they will be closed without action has helped raised the visibility of stale issues/PRs and people being proactive because they want to avoid the autoclose when it does not make sense.

  4. ljharb commented on May 10, 2022

    @ljharb
    SponsorMember

    @mhdawson in my experience it causes a bunch of much noisier "bump" comments, or, it gets closed (and in some projects, auto-locked) and then the problem is forgotten, which is much worse than the open issue being forgotten.

    There's no value in optimizing for "fewer open issues" - the goal should be to optimize for fewer bugs.

  5. mhdawson commented on May 10, 2022

    @mhdawson
    MemberAuthor

    @ljharb I see it as optimizing it for "more value added work" versus "fewer open issues". In this case we are talking only about PR's (I excluded issues as the dynamics are different there). I think a 1 year + stale PR only wastes peoples time (if they go look at PRs and try to help review/land) versus adding value at some point.

  6. ljharb commented on May 10, 2022

    @ljharb
    SponsorMember

    I certainly agree that confining it to just PRs, and having the stale period be a full year (with a warning comment and a waiting period after that), drastically reduces my concerns (but doesn't eliminate them)

  7. mcollina commented on May 11, 2022

    @mcollina
    SponsorMember

    I'm +1 with @mhdawson proposal.

  8. fhinkel commented on May 11, 2022

    @fhinkel
    Contributor

    +1

    I think a bot auto-closing is friendlier than a human closing it.

    If we have hundreds of open pull requests, they're equally "forgotten" as if we close them.

  9. bnoordhuis commented on May 12, 2022

    @bnoordhuis
    Member

    Also +1. I was going through some old PRs this morning that have 0% chance of getting merged but I didn't feel like closing them because you just know it's going to turn into a tedious back-and-forth when the author disagrees. Better to have a bot do it.

    edit: I agree however with @ljharb about "bump" comments. I would make the bot strongly discourage them.

  10. BridgeAR commented on May 18, 2022

    @BridgeAR
    Member

    Also +1 to the suggestion.

  11. mhdawson commented on May 18, 2022

    @mhdawson
    MemberAuthor

    Discussed in the last TSC meeting no objection to proceed.

  12. added
    tsc-agendaIssues and PRs to discuss during Technical Steering Committee meetings.
    and removed
    tsc-agendaIssues and PRs to discuss during Technical Steering Committee meetings.
    on Jun 1, 2022
  13. gireeshpunathil commented on Jun 1, 2022

    @gireeshpunathil
    Member

    I agree to the motivation - reducing the backlog and keeping it small and healthy. On the other hand, there are class of PRs (and the human behind those PRs) that can get hurt a little:

    • PRs that are pending on collaborators
    • PRs that have objections from reviewers with no path forward suggested
    • PRs that were carried away (transformed) in the review and went out of OP's control and skill
    • PRs that reveals flakes in the CI
    • PRs whose OP is genuinely busy with other matters

    I am not saying that all the PRs belong to these categories, or all these types can cause pains to the owners. My personal opinion is that we should make our PR abandonment process as friendly as possible (complimenting with the onboarding process) - a human touch would be much comforting for the owner.

    Can I propose TSC members tasked with reviewing stale PRs each week (in small numbers) and address this one in an incremental, yet sustainable and firendly manner?

  14. removed
    tsc-agendaIssues and PRs to discuss during Technical Steering Committee meetings.
    on Jun 15, 2022
  15. 9 remaining items

  16. mhdawson commented on Jun 6, 2023

    @mhdawson
    MemberAuthor

    That could explain it. The issues showed a force push 7 months ago but not that one (unless I just missed that somehow). Otherwise I would have been looking for something like that.

    The problem is that a force push will affect all of our use of the stale actions (not just this new one) if they occur within every 6 months.

  17. added a commit that references this issue on Jul 6, 2023
  18. added a commit that references this issue on Feb 18, 2024
  19. github-actions commented on Jun 25, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  20. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jun 25, 2026
  21. Ethan-Arrowood commented on Jul 15, 2026

    @Ethan-Arrowood
    Contributor

    Reviving this. I've been triaging the networking-related backlog and that led me to look into why old PRs aren't getting cleaned up from the autonomous stale bot. I did some digging and determined that both of our stale automations share a root issue.

    Research

    Just to clarify, as far as I understand there are two stale automation systems in place. The first one is fully automatic, 240 day counter powered by the stale.yml workflow. The second is manual, 30 day counter powered by the closed-stalled.yml workflow.

    I've come across the same issue Beth and Michael were discussing in this thread previously; "phantom" updates.

    You can see this affecting the automatic flow in #58259 :

    • 2026-04-20 01:43 — bot adds stale + posts the 30-day warning
    • 2026-04-25 01:42 — bot removes stale
    • in between: no commits, no comments, no reviews

    Unfortunately the UI confusingly collapse them into one line "added stale and removed stale on Apr 19". GH API demonstrates it better:

    gh api repos/nodejs/node/issues/58259/timeline --paginate \
      --jq '.[] | (.created_at // .submitted_at // .committer.date // "") as $t
                 | select($t >= "2026-04-19" and $t <= "2026-04-26")
                 | "\($t)  \(.event // .type)  by \(.actor.login // .user.login // .committer.name // "?")"' \
      | sort
    
    2026-04-20T01:43:38Z  commented  by github-actions[bot]
    2026-04-20T01:43:39Z  labeled  by github-actions[bot]
    2026-04-25T01:42:14Z  unlabeled  by github-actions[bot]
    

    The manual flow is a little more resilient (things do actually get closed) because of the shorter timeline, but its not immune. #40883 is a good example of an affected phantom update:

     gh api repos/nodejs/node/issues/40883/timeline --paginate \
      --jq '.[] | (.created_at // .submitted_at // .committer.date // "") as $t
                 | select($t >= "2025-03-28T18:34:37Z" and $t <= "2025-04-03T00:01:37Z")
                 | "\($t[:19])  \(.event // .type)\(if .label then " [" + .label.name + "]" else "" end)  by \(.actor.login // .user.login // .committer.name // "?")"'
    
    2025-03-28T18:34:37  labeled [stalled]  by bjohansebas
    2025-03-28T18:34:46  commented  by github-actions[bot]
    2025-04-03T00:01:37  unlabeled [stalled]  by github-actions[bot]
    

    Both workflows rely on actions/stale which measures inactivity by updated_at. The problem is that updated_at gets bumped by things that aren't true PR activity.

    Thus, I believe Beth's force-push main suspicion is correct, but it's hard to definitely prove because GitHub doesn't expose why updated_at is changed.

    I tried searching main branch commit history to see if there was anything that stood out, but I can't find anything definitive either. My best suspicion is any base-branch movement (and possibly GitHub-internal mergeability recomputation) can bump an open PR's updated_at causing the "phantom" updates.

    Decision Point

    I think the solution is relatively straightforward and depends on one question:

    Do we accept that these phantom updates reset the staleness counter?

    • If yes, then the window will keep getting reset by repo activity, and the only way to close more PRs is to make the window short enough to beat the churn. Drop 240 days to something meaningfully shorter. The manual 30 day is likely okay to remain as is. This is a simple config change, but we remain susceptible to the phantom updates.
    • If no, then we make the workflows resilient by measuring genuine activity instead of relying on updated_at. It could be something like max(last commit committedDate, last non-bot comment, last review). This should meaningfully eliminate the phantom updates and enable our automations to actually close things out as expected.

    I personally prefer the later "no" option, and believe we should fix the automation for real.

  22. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 15, 2026
  23. bmuenzenmeyer commented on Jul 15, 2026

    @bmuenzenmeyer
    Contributor

    As a triager and maintainer of several of our spaces, I don't mind us being more aggressive in closure. The project thrives on momentum. I don't mean it has to be 30 days or else, but would anyone consider no communication for 8 months to be acceptable? The PR is unlikely to land simply due to drift and conflicts. I've personally witnessed a lot more drive by PRs now that never get any response upon providing feedback. If people don't come back right away to nurture a changeset, they likely aren't. (I state this with much empathy, from both sides) Even a 60 day staleness seems acceptable. nodejs/help uses 180 albeit without any of the triggers you identified here resetting things.

    As to whether or not we accept the phantom updates, it sounds a bit out of our control, but building something ourselves feels counterproductive in a different way (maintenance, not expected with norms).

    Perhaps we engage upstream? actions/stale recently had some good feedback/resolution- your analysis might help them narrow down another edge case

  24. Ethan-Arrowood commented on Jul 15, 2026

    @Ethan-Arrowood
    Contributor

    Hm yes I think I'd most-prefer to see this fixed upstream in actions/stale.

    Maybe the best solution is to reduce timing to something like you said, 60 days for auto, 30 manual. And we hope actions/stale fixes its issue?

  25. bmuenzenmeyer commented on Jul 15, 2026

    @bmuenzenmeyer
    Contributor

    Worth noting that https://github.com/actions/stale/releases/tag/v10.3.0 which we just adoptedlast month has a fix for stale labeling itself resetting the timers...

  26. Ethan-Arrowood commented on Jul 16, 2026

    @Ethan-Arrowood
    Contributor

    Okay so maybe things are better now - just need to wait a full month to see if it actually catches and cleans everything up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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