Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

After a merge whose re-read failed, BLOCKED reasons say "nothing was merged"

Aperta
#376 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
1-2 giorni
Idoneità per principianti
46/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
backend

Direzione di ricerca

Start by reading the MERGE step, the step-budget check, and the functions that build BLOCKED reasons, especially _merge_so_far() and _checks_refused_reason; the issue identifies these behaviors but gives no file paths. Reproduce both cases with the FakeGitHub helpers in tests/test_engine.py, where the merge lands and the post-merge re-read fails. Update the reasons so they describe an unknown outcome without claiming nothing was merged, then verify both quoted cases.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

If the controller's re-read of a PR fails right after gh pr merge, the merge outcome is unknown. The run stays in MERGE so that resume can reconcile from GitHub. Two bounds can block the run from that state instead, and both BLOCKED reasons say nothing was merged, although GitHub may already hold the merge.

I found this while addressing the review of #337. It predates that PR and is present on main at 1a9424e.

The two cases

The step budget. The step whose re-read failed is charged when it saves the verification attempt. If it was the last step workflow.max_total_steps allows, the budget blocks the next resume before MERGE runs:

1 step(s) executed in this run and workflow.max_total_steps=1 is reached; no further step is executed. This budget is cumulative for the run and is not reset by 'resume'; nothing was merged. Raise 'workflow.max_total_steps' in the config or start a new run.

#337 lets a MERGE step run past the budget only when an earlier step already counted the merge. This merge was never counted, so that exemption does not cover it.

The verification-attempt bound. If the failed re-read is the merge.max_verification_attempts-th inconclusive verification in MERGE (the first, when the bound is 1), the step blocks at once. The reason contradicts itself:

after gh pr merge the PR could not be re-read: gh pr view failed (exit 1): connection reset. Merge outcome unknown; nothing was counted (an already-merged PR is recovered and counted once on re-check). GitHub data stayed inconclusive for 1 verification attempt(s) (merge.max_verification_attempts=1); giving up. Nothing was merged or counted; inspect the PR on GitHub manually.

On #337's branch, that last sentence comes from _merge_so_far(), which says the same thing for any merge that was not counted.

Evidence

Both cases reproduce against FakeGitHub on main: the merge lands and the single get_pr after it fails. The fake then reports the PR as MERGED, counted_merged_prs is empty, and block_reason is the text quoted above. The scratch test was not committed:

Reproduction (uses the helpers in tests/test_engine.py)
import pytest

from autoforge.errors import VerificationError
from tests.test_engine import PR, SHA_A, _in_merge


def _merge_lands_then_reread_fails(gh):
    real = gh.merge_pr

    def merge_then_break(*a, **kw):
        real(*a, **kw)
        gh.get_pr_failures = 1  # only the post-write re-read fails

    gh.merge_pr = merge_then_break


def test_attempt_bound(tmp_state_dir, fake_github):
    fake_github.add_pr(head_sha=SHA_A)
    eng = _in_merge(tmp_state_dir, fake_github)
    eng.config.merge.max_verification_attempts = 1
    _merge_lands_then_reread_fails(fake_github)
    out = eng.step(allow_merge=True)
    # fake_github.prs[PR].state == "MERGED"; out.next_phase == "BLOCKED"
    # eng.state.block_reason ends "Nothing was merged or counted; ..."


def test_budget(tmp_state_dir, fake_github):
    fake_github.add_pr(head_sha=SHA_A)
    eng = _in_merge(tmp_state_dir, fake_github)
    eng.config.workflow.max_total_steps = eng.state.step_count + 1
    _merge_lands_then_reread_fails(fake_github)
    with pytest.raises(VerificationError):  # "Merge outcome unknown ... attempt 1/5"
        eng.step(allow_merge=True)
    out = eng.step(allow_merge=True)  # resume
    # fake_github.prs[PR].state == "MERGED"; out.next_phase == "BLOCKED"
    # eng.state.block_reason: "... is reached; ... nothing was merged. ..."

Impact

The controller does not act on the wrong text. It counts nothing, the run stays BLOCKED, and recovery works. In the budget case, after the budget is raised, unblock reads the PR, reports that it "is MERGED at the clean-reviewed HEAD ... but not yet counted", and READY_FOR_MERGE → MERGE reconciles and counts the merge once.

The problem is what the operator reads. The budget reason also offers "start a new run" as a remedy. An operator who believes "nothing was merged" could take that route for an issue whose PR has already merged, instead of reconciling it. Triggering either case needs a GitHub failure in the short window between gh pr merge and its re-read, on a step where one of the two bounds is reached.

Desired outcome

When the merge outcome is unknown, no BLOCKED reason says nothing was merged. A reason either says the outcome is unknown, or reads GitHub and says what it holds, as _checks_refused_reason already does for a refused checks read.

Open question

Should a MERGE step whose outcome is unknown also run past the budget, the way #337 lets a counted one run? That would let resume reconcile without an operator. But if the merge did not land and the PR is still OPEN, that step would verify the PR again and send gh pr merge past the budget. #337's exemption is safe only because MERGE refuses to merge a PR the run already counted, and an uncounted PR has no such guard. Fixing only the wording avoids that question.

Unknown

How often a re-read fails right after a successful gh pr merge in real runs. I don't know of a run log that shows it.

Lingua principale
Python
Stelle
0
Fork
0
Merge medio
5h 46m
PR unite (30g)
82

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di iceboundrock/AutoForge

Tutte le issue di iceboundrock/AutoForge

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.