Skip to content

fix(pr-pipeline): read auto-merge state back when a resent arm or disarm errors #9547

Open

Description

@kyle-sexton

Problem

.github/scripts/pr-merge/enable-auto-merge.mjs resends an arm or disarm mutation after a transient network error. If the first attempt reached GitHub but its answer was lost, the resend can return an error even though the pull request already holds the target state. GitHub does not document how enablePullRequestAutoMerge answers on an already-armed pull request (https://docs.github.com/en/graphql/reference/pulls). The step then exits 1 on a correct outcome. A red pr-merge run counts toward the two-failure revert rule and the gate-repeat alert, so it is false evidence.

Fix

When a resent arm or disarm returns an error, read the pull request's autoMergeRequest once. Count it a success when the state already matches the target: armed at the same head for an arm, unarmed for a disarm.

Done when

  • A resend that errors after a lost first answer, with the pull request already in the target state, logs a success and does not fail the step.
  • A resend that errors while the state does not match still fails, naming the pull request and the cause.
  • Tests cover both cases.

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 24, 2026
  2. github-actions commented on Oct 24, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Medium
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: when enable-auto-merge.mjs resends an arm or disarm after a transient network error and the resend returns an error, the step should read autoMergeRequest back once. It should log success if the state already matches the target (armed at the same head, or unarmed) and fail otherwise, naming the pull request and the cause. Tests should cover both cases. The scope and done-when items are clear and checkable. I found no likely duplicates.

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 24, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 24, 2026
  5. melodic-automation-lanes commented on Oct 24, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue lane did not start this issue: it needs a person to make it clearer first.

    Why, in the run's own words:

    The issue's premise does not match the code: nothing resends an arm or disarm mutation. enable-auto-merge.mjs (lines 494-505) sends each arm/disarm GraphQL POST once through createGitHub, and retryServerErrors in .github/actions/check-trusted-trigger/check-trusted-trigger.mjs (line 143) retries only GET requests ('Only GETs are idempotent'; a test at check-trusted-trigger.test.mjs:1949 asserts a failing POST is not resent). So there is no resend whose error could follow a lost first answer. Question for a person: (a) is the false red from a different path (e.g. a failed first send, an expectedHeadOid mismatch, or a stale run), in which case which run or log shows it; or (b) should the readback apply to ANY arm/disarm error (a single send that fails, with the state read back once and counted a success when armed at the same head / unarmed), without adding a resend; or (c) should POST resends be added first? Option (b) changes the issue's scope, so it needs a recorded decision.

    What the run says it did not do:

    • Readback of autoMergeRequest after an arm/disarm error, and its tests: not started because the issue leaves open whether it applies to a single failed send, since no resend exists

    Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/40054893459

    To retry, answer the question here, remove needs-human and add agent-ready again.

  6. removed
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Oct 24, 2026
  7. kyle-sexton commented on Oct 25, 2026

    @kyle-sexton
    MemberAuthor

    Re-checked on main (2d9ac7f): the earlier pushback's premise, that nothing resends the arm/disarm mutation, came from lane run 40054893459, which started at 02:36Z on a base older than #9545 (merged 03:58Z). On main, withRetry in .github/scripts/pr-merge/enable-auto-merge.mjs:197-241 resends both GraphQL POSTs on network errors, the comment at :214-218 describes this issue's bug, and the catch at :872-904 never reads autoMergeRequest back. The issue stands as written; releasing it for re-triage.

  8. removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 26, 2026
  9. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    Released for re-triage under the owner's 2026-10-26 rule: a person is involved only for "1. A change in original intent/vision 2. Something comes up during implementation ... that alters intent/vision or the primary design 3. If there is a HIGH/CRITICAL security issue". None applies here, so the hold label came off and intake triage runs again now.

    To hold this issue again, add needs-human (or status: needs-decision) and name which of the three applies.

  10. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    Released for re-triage under the owner's 2026-10-26 rule: a person is involved only for "1. A change in original intent/vision 2. Something comes up during implementation ... that alters intent/vision or the primary design 3. If there is a HIGH/CRITICAL security issue". None applies here, so the hold label came off and intake triage runs again now.

    To hold this issue again, add needs-human (or status: needs-decision) and name which of the three applies.

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

    priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions