theonedev/onedev · error · UnauthorizedException

Code write permission is required to edit auto merge

Error message

Code write permission is required to edit auto merge

What it means

Toggling the 'autoMerge' field requires code write permission on the pull request's project, checked via SecurityUtils.canWriteCode(). The current authenticated user lacks that permission, so the endpoint throws UnauthorizedException before any state checks.

Source

Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:1432

                    review.setStatus(PullRequestReview.Status.EXCLUDED);
                    excludedReviews.add(review);
                }
            }
            pullRequestService.checkReviews(request, false);
            var requiredReviewers = excludedReviews.stream()
                    .filter(it -> it.getStatus() != PullRequestReview.Status.EXCLUDED)
                    .map(it -> it.getUser().getName())
                    .collect(Collectors.toList());
            if (!requiredReviewers.isEmpty())
                throw new NotAcceptableException("Unable to remove mandatory reviewers: " + String.join(", ", requiredReviewers));
            for (var review : excludedReviews) 
                pullRequestReviewService.createOrUpdate(user, review);
        }

        var autoMergeEnabled = (Boolean) data.remove("autoMerge");
        if (autoMergeEnabled != null) {
            if (!SecurityUtils.canWriteCode(request.getProject()))
                throw new UnauthorizedException("Code write permission is required to edit auto merge");
            if (!request.isOpen())
                throw new NotAcceptableException("Pull request is closed");

            if (autoMergeEnabled && request.checkMergeCondition() == null) 
                throw new NotAcceptableException("This pull request is not eligible for auto-merge, as it can be merged directly now");

            var autoMerge = new AutoMerge();
            autoMerge.setEnabled(autoMergeEnabled);
            autoMerge.setCommitMessage(trimToNull((String) data.remove("autoMergeCommitMessage")));
            var errorMessage = request.checkMergeCommitMessage(user, autoMerge.getCommitMessage());
            if (errorMessage != null) 
                throw new NotAcceptableException("Error validating param auto merge commit message: " + errorMessage);

            pullRequestChangeService.changeAutoMerge(user, request, autoMerge);
        }
                    
        return PullRequestHelper.getDetail(currentProject, request);        
    }    

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the user (or the bot's account) code write permission on the project (Project -> Access Control).
  2. Perform the auto-merge edit with an account/token that has write access.
  3. If the caller should not have write access, have an authorized user toggle auto-merge instead.
  4. Drop the 'autoMerge' field from the request if only other fields (title, labels, etc.) need editing.

Example fix

// before
// bot token with read-only role calls:
await editPullRequest(ref, { autoMerge: true });
// after
// use a service account with code write permission, or skip:
if (await canWriteCode(project)) {
  await editPullRequest(ref, { autoMerge: true });
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side pre-check
const perms = await getMyProjectPermissions(project);
if (!perms.includes('write code')) throw new Error('autoMerge requires code write permission');

Type guard

function canEditAutoMerge(perms) { return perms.includes('write'); }

Try / catch

try {
  await editPullRequest(ref, { autoMerge: true });
} catch (e) {
  if (e.status === 401 || e.status === 403) {
    // request elevation or fall back to a service account with write access
  }
}

Prevention

When it happens

Trigger: POST /edit-pull-request with a non-null 'autoMerge' value while the caller is authenticated as a user without write access to the project's code (e.g. read-only role or non-member).

Common situations: AI agents or bots running with restricted tokens trying to enable auto-merge; users with only read/reporter roles attempting auto-merge via API; token scoped to a project where the identity lacks commit rights.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/d13b15b45b34374c. Report an issue: GitHub.