Skip to content

pr-standards needs:issue is a false positive for v2-based PRs because the runner uses the dev copy of the workflow #51057

Closed

Description

@Tsuki-hash

Description

needs:issue is still applied to every PR that targets v2, even when the description references an issue exactly as the template asks. #43964 fixed this by falling back to a PR-body check, and that fix is in .github/workflows/pr-standards.yml on v2 since 2026-08-25 — but not on dev, which is the default branch, and pull_request_target executes the default branch's copy of the workflow. So the corrected check lives in the tree that ships and is absent from the copy that actually runs.

Evidence from the run on PR #51052 (base v2, opened today): the script echoed by its check-standards job contains if (linkedIssues === 0) and zero occurrences of hasBodyIssueRef, which is dev's copy. Consequence right now: 141 open PRs carry needs:issue, among them #51035 and #51043, whose description carries Closes #51041.

Why the GraphQL check alone cannot work here: closingIssuesReferences is only populated for PRs that target the repository default branch, so a v2 PR reports totalCount 0 however well-formed its description is.

What dev needs is the same nine lines #43964 added on v2.

Plugins

Not applicable, this is about the CI workflow.

OpenCode version

Not a product version: .github/workflows/pr-standards.yml, dev copy as of 0f54984.

Steps to reproduce

  1. Open or edit any PR whose base is v2 with Fixes #<issue> inside the ### Issue for this PR section.
  2. Wait for pr-standards → check-standards.
  3. The PR gains needs:issue and the "doesn't have a linked issue" comment even though the reference is there.

Operating System

Any; the check runs on ubuntu-latest and the defect is branch-independent.

Terminal

Not applicable.

Activity

  1. Veld101 commented on Sep 27, 2026

    @Veld101

    Independent confirmation from an affected contributor — my six fix(...) PRs against v2 all carry needs:issue with closingIssuesReferences 0, while the same style of body links fine on dev:

    PR base body says linked label
    #51070 v2 Closes #49216 0 needs:issue
    #51018 v2 Closes #51014 0 needs:issue
    #50836 v2 Closes #50426 0 needs:issue
    #50801 v2 Closes #48259 0 needs:issue
    #50797 v2 Closes #50338 0 needs:issue
    #50796 v2 Closes #50474 0 needs:issue
    #50911 dev Closes #50807 1 —
    #50927 dev Closes #50722 1 —

    Two things I did not see stated, which may be worth adding to the description:

    1. Only fix-titled PRs are hit. check-standards returns early for docs/refactor/feat titles (skipIssueCheck), and that branch also removes the label. So feat(tui): … against v2 is fine and fix(tui): … is not. That is why it reads as inconsistent rather than universal — every PR in the table above is a fix.

    2. The label is sticky once applied. The only removeLabel('needs:issue') paths are the skipIssueCheck branch and the linkedIssues > 0 case, which a v2 base can never satisfy, and the job only triggers on opened/edited/synchronize. So after fix(ci): apply the PR body issue fallback on the default branch copy #51058 lands, the ~141 already-labeled PRs will not clear themselves: each author has to push a commit or edit the PR, or a maintainer removes the labels in bulk. A workflow_dispatch backfill (or a note in the contributing guide) would close that gap.

  2. Tsuki-hash commented on Sep 27, 2026

    @Tsuki-hash
    Author

    @Veld101 both additions hold up against the workflow source, and the counts are worse than the 141 I quoted: as of today 181 open PRs carry needs:issue, 169 of them fix-titled against v2. Your read of the mechanism is exactly right:

    • skipIssueCheck (pr-standards.yml:112-115) covers docs/refactor/feat and also removes the label, which is why the pattern looks like a fix-only bug rather than a blanket one.
    • The only removeLabel('needs:issue') paths are that branch and the fall-through after the linked check (:161), and the job triggers only on opened/edited/synchronize. With a v2 base the fall-through was unreachable before fix(ci): apply the PR body issue fallback on the default branch copy #51058, so every labeled PR stays labeled until its author edits or pushes.

    One practical nuance for the already-labeled set: once #51058 is live, a re-trigger is enough - any edit or push re-evaluates the body and takes the clear path, so fix PRs on v2 do not need a new commit with new content, just an event. Whether to also add a backfill (bulk label removal, or a workflow_dispatch path) is the maintainers' call rather than something to fold into the fix; a dispatch run has no pull_request payload, so that script needs its own listing path.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report. I copied the check-standards script out of the workflow and ran it against a mocked GitHub API. The test PR was a fix(...) PR on base v2 with Closes #51041 in the ### Issue for this PR section, with closingIssuesReferences returning 0 as you described.

    • pr-standards.yml at 0f54984 (the copy you reported): it added needs:issue and posted the "doesn't have a linked issue" comment, so it reproduced.
    • Latest dev (fa1260d): after v2 was promoted to dev, the workflow is now triage-pr-standards.yml and includes the PR-body fallback from fix(ci): check PR body for linked issue on non-default branches #43964 (hasBodyIssueRef). The same PR passes and needs:issue is removed.

    So this looks fixed on the default branch now. PRs that were labelled before the change may keep a stale needs:issue until their next edit or push, as noted on #51058.

    Related: #51970 (the same report, closed as a duplicate of this one), #43964 (the original fix on v2), #51058 and #51971 (backport PRs).

    The bot will close this issue in 1 day unless you reply that it still happens.

  4. Tsuki-hash commented on Oct 28, 2026

    @Tsuki-hash
    Author

    Thanks for verifying this. The fix on latest dev (the triage-pr-standards.yml with the hasBodyIssueRef fallback from #43964) matches what I reported, and I am happy with that resolution. The stale-label note for previously labelled PRs is already tracked in #51058, so it does not need to block this one. Feel free to close this issue.

  5. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

    Closing this as completed, since there's been no reply for a day. With pr-standards.yml at 0f54984, a fix(...) PR with Closes #... in its description got a false needs:issue. With the current dev workflow (triage-pr-standards.yml at fa1260d) it doesn't, because the PR-body fallback from #43964 is now on the default branch. This is a CI workflow, so the fix already applies to new runs and doesn't need a release. PRs labelled before the change may keep a stale needs:issue until their next edit or push, as noted on #51058.

    If you still see the false label on a PR after editing or pushing to it, please comment here or open a new issue with a link to the run. Thanks for the clear write-up and the evidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions