Skip to content

[scanner] close-on-merge closes a PR as a "fixed issue" when a sibling-repo PR mentions it #14744

Closed

Description

@hivecommons-hive

Finding

closeIssueForMergedPRClaimWithIssue (src/pkg/github/close_on_merge.go, v5 ~L482-545) treats whatever Issues.Get returns as an issue. GitHub's Issues API also returns pull requests, and the function never calls issue.IsPullRequest() before posting the Fixed by #N (merged …). Closing. comment and closing the target. The backfill loop (~L267) does skip issue.IsPullRequest(), but the ledger-claim path (~L194-228) does not, and neither does the shared close function they both end in.

Observed: #14730 — an open PR against v5 — was closed by the hive with:

Fixed by #25 (merged 2592e5439fd2). Closing. Reply /reopen if the problem persists.

2592e5439fd2 is hivecommons/crux's merge commit for crux#25, whose body says "the fix is made in hive (#14730 …)". That cross-repo mention became a claim with Repo=hivecommons/hive, Issue=14730, PRRepo=hivecommons/crux, PRNumber=25, and the claim path closed the hive PR as though it were the issue crux#25 fixed. Nothing from #14730 had landed on v5; it was reopened by hand.

Why it matters

A PR that is still waiting on CI is silently closed with a misleading "Fixed by" comment pointing at another repository's commit, and the actual fix never merges. Any multi-repo hive that mirrors a change (hive ↔ crux, hive ↔ docs) and mentions the sibling PR by number is exposed.

Fix

In closeIssueForMergedPRClaimWithIssue, after the issue is fetched (or supplied), skip with Action=CloseOnMergeSkipped, Reason="target_is_pull_request" when issue.IsPullRequest(). Log at INFO (metadata verdict, not a failed step — same reasoning as issue_not_found). Add a table-driven case in close_on_merge_test.go where the fetched target has PullRequestLinks set and assert no close/comment call is made.

Decision taken by hive: guard at the shared close function (covers both the claim and backfill paths) rather than at claim-record time; it is additive and keeps existing reasons/ids unchanged.

Priority

  • Impact: high — closes live PRs with a false "fixed" record
  • Effort: low — one guard + one test case

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

Activity

  1. added
    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
    on Oct 28, 2026
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

    agent/scannerCreated or modified by the scanner agentbugSomething isn't workinghelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.hive/claimed-by-scanner

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions