Skip to content

Fix pulls stuck open after a missed close webhook - #501

Draft
probablyian wants to merge 1 commit into
masterfrom
reconcile-stale-open-pulls
Draft

probablyian wants to merge 1 commit into
masterfrom
reconcile-stale-open-pulls

Conversation

@probablyian

Copy link
Copy Markdown
Member

🤖

Closed PRs can stay on the board forever. Pulldasher finds out a PR closed when GitHub sends it a notification. If that notification is missed, for example while pulldasher is down, the PR stays open on the board. Restarting doesn't fix it, because the startup refresh only asks GitHub for open PRs.

On 2026-09-11 the board listed 312 open PRs, and 4 of them had closed on GitHub on 2026-08-28, including iFixit/ifixit#64052 under Dev Blocked. Now startup also re-checks each PR the database still has as open that GitHub didn't list, so those 4 leave the board once pulldasher restarts with this change.

Summary

  • Startup refresh: once the boot refresh in app.js finishes the open-PR list, openPulls() loads every pull the DB holds as open and refetches the ones GitHub didn't list.
  • bin/refresh-open-pulls: calls the same function, so running it by hand clears stuck pulls too.

This doesn't cover a pull that closes during the startup refresh, which can be saved back as open; the commit message explains why. If loading open pulls from the DB fails, bin/refresh-open-pulls logs it and still exits 0.

The 4 stuck pulls (all closed 2026-08-28, times in UTC)
Pull GitHub state Closed at
iFixit/ops#765 merged 03:38
iFixit/ops#696 merged 03:51
iFixit/DocHarvestor#242 merged 03:53
iFixit/ifixit#64052 closed 16:27

QA

  • Run npm test on Node 24 and confirm test/stale-open-pulls.test.js passes. CI only runs lint and build.
  • Deploy this branch and restart pulldasher.
  • Confirm iFixit/ifixit#64052 is gone from Dev Blocked on the Classic board.
  • Confirm the other 3 pulls in the table are gone from the board.

https://claude.ai/code/session_01Jd4HCBx9fmiVVyuziBg1HQ

A closed PR can stay on the board forever. Pulldasher finds out a pull
closed from GitHub's pull_request webhook. If that delivery is lost, the
pull's row keeps state 'open' until something else refreshes that pull.
Nothing does on its own. The startup refresh only lists the pulls GitHub
reports as open, and a closed pull is never in that list.

https://github.com/iFixit/pulldasher/blob/f924c742c208c2e52ce568b4f0a4998c46693a9c/app.js#L96-L99
https://github.com/iFixit/pulldasher/blob/f924c742c208c2e52ce568b4f0a4998c46693a9c/lib/git-manager.js#L165-L171

On 2026-09-11 the board showed 312 open pulls, and 4 of them were
already closed on GitHub, all on 2026-08-28 (times in UTC):

  iFixit/ops#765           merged 03:38
  iFixit/ops#696           merged 03:51
  iFixit/DocHarvestor#242  merged 03:53
  iFixit/ifixit#64052      closed 16:27

I can't read the server logs. A pulldasher container on the host started
at 17:35 that day, and the next pull to close after that
(iFixit/fixbot#3276, 17:43) isn't stuck.

Now openPulls() ends by loading every pull the DB holds as open and
refetching each one the listing left out, which saves its real state.
It skips repos whose listing failed, since a failed listing says nothing
about which of their pulls closed. It runs once at startup, and from
bin/refresh-open-pulls, which calls the same function. When nothing is
stale it adds one DB query and no GitHub calls.

Solutions considered:

1. Also re-check every hour. That clears a stuck pull without waiting
   for a restart; we went with startup only.
2. Schedule bin/refresh-all-pulls. It lists every pull ever opened in
   each repo, 36,659 in ifixit alone.

Note: this doesn't cover a pull that closes while the startup refresh
is still working through its listing. The refresh saves the state it
listed, and DBPull.save() is a plain REPLACE, so if that write comes
after the close webhook's write, the pull is open again.

Claude-Session: https://claude.ai/code/session_01Jd4HCBx9fmiVVyuziBg1HQ
@probablyian

Copy link
Copy Markdown
Member Author

@jarstelfox I found one of my closed pulls listed in pulldasher and this was the result of the investigation. Any concerns with these changes?

@jarstelfox

jarstelfox commented Sep 11, 2026

Copy link
Copy Markdown
Member

@probablyian The only concern is I haven't merged #486 which is what cominor has been running

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants