Found while releasing v1.13.1.
Amending a commit and force-pushing the branch left the builds already queued against the abandoned commit in the queue. They then ran and failed:
$ git clone ssh://git@127.0.0.1/krz/gitbay.git (d69a1511bf)
fatal: unable to read tree (d69a1511bf753ba1605f024c4e8c2c2958a7438a)
git -C: step failed: exit status 128
Five builds across two force-pushes did this in one afternoon (655–658 and 662). They show as failure in build list alongside real results, and the message names a git internal error rather than the actual cause, which is that nothing points at that commit any more.
Two costs. A red build that means nothing trains a reader to ignore red, which is the state a gating CI exists to prevent. And it actively misleads: I read 662 failure vuln and spent time believing a new advisory had landed against unchanged code, because vuln failing is exactly what that looks like.
QueueBranchBuilds records sha at push time, and nothing revisits that queue when the ref moves. The runner claims the build later and clones a commit no ref reaches.
Remedy: when a ref update leaves a queued build's sha unreachable from any ref, cancel it as obsolete rather than letting it run. build cancel already exists and cancelled is already a status the UI renders, so this is a matter of noticing at ref-update time — post-receive already has the old and new values.
Worth deciding alongside: whether a running build for a superseded commit should also be cancelled. A force-push while the suite is running is common, and finishing a build of code nobody will merge costs a runner slot. Cancelling it is defensible, but so is letting it finish, since its log may be the reason someone force-pushed. Cancelling only queued builds is the smaller, safer change.
closed by commit f994d5a21a by cmc: control: cancel a build orphaned by force-push when a runner claims it
2026-09-05 21:17 UTC