Skip to content

Merge run leaves the issue open when the merge doesn't close it #181

Closed

Description

@JacobStephens2

This was generated by AI during triage.

A Merge run on the maintainer's machine merged #168 into main, but #158 stayed open, even though #168's body says Closes #158. The Run ended with:

thirdshift: warning: could not close issue #158, so if it is still open, close it by hand: gh issue close 158 --repo JacobStephens2/thirdshift --comment 'Closed by #168, merged into main by a thirdshift Merge run.'
thirdshift: cleaning up the worktree and local branch issue-158
thirdshift: PR https://github.com/JacobStephens2/thirdshift/pull/168 is merged

Just before the warning, stderr has gh's "Unknown JSON field" list of fields, which it prints when asked for a field it doesn't support.

Two causes:

  1. thirdshift asks gh for a field older versions don't support. To decide whether the merge closes the issue by itself, the Self-merge's post-merge step runs gh pr view --json baseRefName,closingIssuesReferences. The machine has gh 2.45.0 (Ubuntu's package), which rejects closingIssuesReferences, so the step fails and turns into the warning. The fake gh in the tests supports the field, so the suite never sees this.
  2. GitHub didn't close the issue either. GraphQL shows Release script resumes an interrupted release #168 linking Release script resumes an interrupted release #158 for closing, and Release script resumes an interrupted release #168 merged into main, the default branch, yet Release script resumes an interrupted release #158 has no close event. One Run notification per Spec run #148 behaved the same after One Run notification per Spec run #170 merged: it was closed by hand five minutes later. So even with a newer gh, thirdshift would have trusted GitHub to close Release script resumes an interrupted release #158, skipped closing it itself, and left it open.

Activity

  1. JacobStephens2 commented on Sep 30, 2026

    @JacobStephens2
    OwnerAuthor

    This was generated by AI during triage.

    Agent Brief

    Category: bug
    Summary: After a Self-merge, thirdshift closes the issue itself if it is still open, without trying to predict whether GitHub will close it.

    Current behavior:
    After the merge, the Self-merge asks whether merging closes the issue (github::merge_closes_issue). It checks that the PR's closingIssuesReferences includes the issue and that the PR's base is the repository's default branch. If both hold, thirdshift leaves the closing to GitHub.

    • With gh older than the release that added closingIssuesReferences to gh pr view --json (2.45.0 in this report), the question fails. The Run warns "could not close issue #N…" and the issue stays open. This happens on every Merge run on that machine.
    • With a newer gh, the answer is "yes" for a PR into the default branch. thirdshift then skips closing, so when GitHub doesn't close the issue (as in this repo, see Release script resumes an interrupted release #158 and One Run notification per Spec run #148), it stays open with no warning at all.

    Desired behavior:
    After a Self-merge, the issue ends up closed whether or not GitHub closes it. thirdshift closes it with its usual comment ("Closed by #, merged into by a thirdshift Merge run.") unless it is already closed when thirdshift checks. The step no longer reads closingIssuesReferences or compares the base with the default branch.

    Everything else about the post-merge steps stays as it is: they never fail the Run, a failed close is still a warning naming the command to run by hand, and an interrupt still doesn't stop them.

    Race to accept: GitHub closes linked issues a moment after the merge. If thirdshift's check sees the issue open and GitHub closes it at the same moment, the issue may get thirdshift's comment on top of GitHub's close. That's fine. Don't add sleeping or polling to avoid it.

    Key interfaces:

    • github::merge_closes_issue: remove it, along with its only use in the post-merge close step (close_unless_merge_does or whatever it's called by then). The step becomes "close unless already closed", using github::issue_is_open and github::close_issue.
    • The fake gh used by the tests: it currently always emits closingIssuesReferences. Once nothing asks for it, it can reject the field the way gh 2.45 does (Unknown JSON field), so a future use of it fails in tests. Remove the fake's closing-keyword handling if nothing else needs it.
    • CONTEXT.md's Self-merge entry ends "the issue closed, by thirdshift if the merge did not close it". Update it if the wording no longer matches, e.g. "closed by thirdshift unless it is already closed".

    Acceptance criteria:

    • A Merge run whose PR body has Closes #N and whose base is the default branch closes issue #N with thirdshift's comment when the fake GitHub leaves it open after the merge.
    • A Merge run whose issue is already closed when the post-merge step runs doesn't close it again or comment.
    • A Merge run into a non-default base (e.g. a Ticket's Run into a Spec branch) still closes the issue as it does today.
    • No gh call thirdshift makes asks for closingIssuesReferences. A test fails if one does, because the fake gh rejects the field.
    • A failed gh issue close still ends the Run with exit 0 and the existing "could not close issue #N…" warning.
    • cargo test, cargo clippy --all-targets and cargo fmt --check pass.

    Out of scope:

    • Finding out why GitHub doesn't auto-close linked issues in this repo (probably a repository setting). That's for the maintainer to check.
    • Checking gh's version, or setting a minimum version, anywhere else in thirdshift.
    • Closing Release script resumes an interrupted release #158 itself (done by hand during triage).
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

    bugSomething isn't workingready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions