Fourth CI fault: 111+ repos pin an orphaned action SHA, which makes a lockfile impossible
Found while remediating the estate for Workflow Dependency Locking (#657). Five of the first 34 repos swept failed at the same point, with the same cause.
The error
1 action could not be resolved — 2 workflows affected
dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7
no tag or branch contains this commit — a symbolic ref is required for the lockfile
gh actions-lock cannot emit an entry for a commit that no ref points at, so no lockfile can be produced for the repo at all — and without a lockfile, every workflow that needs one stays dead. One unresolvable pin bricks the whole repo.
Measured
|
|
commit 4be9e76f… |
exists upstream, dated 2025-12-16 — but orphaned (force-pushed off its branch) |
tags dtolnay/rust-toolchain publishes |
exactly one: v1 → 6c977a6ca407… |
| repos pinning the orphaned SHA |
111 (code-search floor — it undercounts, see #668) |
Known-affected so far: jtv-lang, coord-tui, social-media-tools, KnotTheory.jl, presswerk.
⚠️ Why SHA-pinning made this worse, not better
The estate pinned actions to full SHAs for supply-chain safety — correct in principle. But a SHA is only durable if a ref keeps it alive. When upstream force-pushes, the commit survives (GitHub keeps unreferenced objects) and workflows kept working, so nothing surfaced. The pin only became fatal when lockfile generation started demanding a symbolic ref.
So this failure was latent for eight months and was triggered by a GitHub feature rollout, not by any change here.
The fix
Repin dtolnay/rust-toolchain@4be9e76f… → @6c977a6ca407… (the v1 tag), estate-wide.
Generalised, this wants a check nobody has: for every pinned action SHA, assert some tag or branch contains it. That is exactly what gh actions-lock does internally, so the detector already exists — it just needs running as a gate rather than discovered during remediation.
Suggested deliverables
- Repin the 111+ references to the
v1 SHA (mechanical).
- A sweep for other orphaned pins — this is unlikely to be the only one; prior estate audits found unresolvable pins in bulk.
- A hypatia rule or CI gate: pinned SHA must be reachable from a ref. Cheap to implement, and it would have caught this before the rollout made it fatal.
Related: #657 (the three faults this is the fourth of), #668 (why the 111 is a floor).
Fourth CI fault: 111+ repos pin an orphaned action SHA, which makes a lockfile impossible
Found while remediating the estate for Workflow Dependency Locking (#657). Five of the first 34 repos swept failed at the same point, with the same cause.
The error
gh actions-lockcannot emit an entry for a commit that no ref points at, so no lockfile can be produced for the repo at all — and without a lockfile, every workflow that needs one stays dead. One unresolvable pin bricks the whole repo.Measured
4be9e76f…dtolnay/rust-toolchainpublishesv1→6c977a6ca407…Known-affected so far:
jtv-lang,coord-tui,social-media-tools,KnotTheory.jl,presswerk.The estate pinned actions to full SHAs for supply-chain safety — correct in principle. But a SHA is only durable if a ref keeps it alive. When upstream force-pushes, the commit survives (GitHub keeps unreferenced objects) and workflows kept working, so nothing surfaced. The pin only became fatal when lockfile generation started demanding a symbolic ref.
So this failure was latent for eight months and was triggered by a GitHub feature rollout, not by any change here.
The fix
Repin
dtolnay/rust-toolchain@4be9e76f…→@6c977a6ca407…(thev1tag), estate-wide.Generalised, this wants a check nobody has: for every pinned action SHA, assert some tag or branch contains it. That is exactly what
gh actions-lockdoes internally, so the detector already exists — it just needs running as a gate rather than discovered during remediation.Suggested deliverables
v1SHA (mechanical).Related: #657 (the three faults this is the fourth of), #668 (why the 111 is a floor).