Skip to content

[Bug]: Forgejo/Gitea merge fails for repo admins on approval-protected branches (missing force_merge) #18755

Closed as not planned

Description

@gustavohariel

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Use a Gitea or Forgejo repo whose branch protection on the target branch requires at least one approval.
  2. Open a PR into that branch as a repo admin, with no approvals yet.
  3. In the T3 pull request panel, click Merge.

Expected behavior

The merge goes through, like the Gitea web UI. There the admin sees a normal merge button plus the notice "As an administrator, you may still merge this pull request", and the merge succeeds.

Actual behavior

Could not merge this pull request
Forgejo API request failed (HTTP 405): {"message":"Does not have enough approvals", ...}

Impact

Major degradation or frequent failure

Version or commit

0.0.46-nightly.20261012.3021

Environment

Linux, desktop app, Forgejo provider against a Gitea server

Cause

The merge action posts only the merge method:

POST /api/v1/repos/{owner}/{repo}/pulls/{index}/merge
{ "Do": "<merge method>" }

Gitea and Forgejo enforce branch protection on admins too. An admin bypasses it only when the request sets force_merge: true. force_merge appears nowhere in the build I checked.

The GitHub provider is not affected: it uses the GraphQL mergePullRequest mutation, which has no override field, and GitHub decides admin bypass from the protection rule or ruleset.

Suggested fix

Keep the merge button as it is, with no second button or extra menu entry:

  1. When the viewer is a repo admin and the PR is blocked by protection (missing approvals, failing required checks), send force_merge: true with the merge request.
  2. Show a short notice in the panel, "As an administrator, you may still merge this pull request", so the override is visible before the click.

Admin status can come from permissions.admin on GET /repos/{owner}/{repo}. If the rule has "block admin merge override" enabled, Gitea rejects force_merge; show the server's error as-is. force_merge is part of the public merge API on both Gitea and Forgejo, so one change covers both. I read the cause from the installed build and have not read Gitea's source; that the web UI sends the flag automatically for admins is inferred from its behavior.

Workaround

Merge from the Gitea web UI, which applies the admin override.

Activity

  1. juliusmarminge commented on Oct 12, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the detailed report. This isn't a bug: the merge is behaving as designed.

    • The Forgejo merge action is in packages/source-control-forgejo/src/server/ForgejoPullRequestProvider.ts (runAction → case "merge"). It POSTs { Do: mergeMethod } to /pulls/{index}/merge with no override. Merge permission is based only on repo.permissions.push (permissions()). Nothing reads permissions.admin, and the panel has no concept of overriding branch protection.
    • The HTTP 405 "Does not have enough approvals" is Forgejo/Gitea enforcing your branch protection rule. T3 passes that through correctly. In the web UI, merging without approvals as an admin is a deliberate override that you choose, not the default merge path.

    Having T3 send force_merge: true silently for admins would add a new capability: bypassing protection from the app. That's the same kind of request as the GitHub admin-bypass idea in #17771 (see also #13065). It's a product decision, so it belongs in Ideas rather than the bug tracker. Feel free to open one there, or add your Forgejo/Gitea use case to #17771.

    Workaround: merge from the Forgejo/Gitea web UI, which applies the admin override.

    Closing as not planned for the tracker.

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

    via-triageFiled through npx t3 triagewontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions