Summary
Reviewer clean-review policy can choose APPROVE, but GitHub rejects approvals on the current user's own pull requests with HTTP 422. Looper then retries the same impossible operation and eventually fails the reviewer loop.
Evidence
Recent examples:
loop 271 — powerformer/looper#180
loop 322 — nexu-io/open-design#421
Both attempted:
looper review submit <repo>#<pr> --event APPROVE --commit-id <sha> --clean-review-event APPROVE --blocking-review-event REQUEST_CHANGES
GitHub response:
{
"message": "Unprocessable Entity",
"errors": ["Review Can not approve your own pull request"],
"documentation_url": "https://docs.github.com/rest/pulls/reviews#create-a-review-for-a-pull-request",
"status": "422"
}
Final queue/run state becomes:
last_error_kind = retryable_after_resume
last_error = Reviewer agent reported a clean summary-only result, but clean review policy requires an APPROVED review marker...
attempts = 3
status = failed
Root cause
The reviewer policy requires a clean APPROVE marker, but GitHub disallows approval when the authenticated user is also the PR author. The trusted wrapper surfaces the 422, but the reviewer keeps requiring an APPROVE marker on resume, causing repeated failure.
Relevant code paths:
internal/reviewer/runner.go:2104-2134 — clean summary handling requires an APPROVED marker when clean policy is APPROVE
internal/reviewer/runner.go:2144+ — publish verifies clean marker policy
looper review submit path surfaces GitHub 422 from gh but does not appear to downgrade own-PR approval to a comment/no-op
Expected behavior
Looper should not repeatedly attempt an impossible GitHub approval on the current user's own PR.
Acceptable behavior:
- Detect
author == current user before choosing APPROVE and use a clean COMMENT fallback with a valid Looper marker, or
- submit a COMMENT with
outcome=clean and mark the run skipped/clean_noop, or
- classify the run as a non-error skip with a clear message.
Proposed fix
- During review/publish, fetch current login and PR author before selecting clean review event.
- If
cleanReviewEvent == APPROVE but current user owns the PR, downgrade to COMMENT or a configured fallback.
- Treat GitHub 422
Can not approve your own pull request as a deterministic policy mismatch, not a retryable transient.
- Add tests for own-PR clean review behavior.
Summary
Reviewer clean-review policy can choose
APPROVE, but GitHub rejects approvals on the current user's own pull requests with HTTP 422. Looper then retries the same impossible operation and eventually fails the reviewer loop.Evidence
Recent examples:
Both attempted:
GitHub response:
{ "message": "Unprocessable Entity", "errors": ["Review Can not approve your own pull request"], "documentation_url": "https://docs.github.com/rest/pulls/reviews#create-a-review-for-a-pull-request", "status": "422" }Final queue/run state becomes:
Root cause
The reviewer policy requires a clean
APPROVEmarker, but GitHub disallows approval when the authenticated user is also the PR author. The trusted wrapper surfaces the 422, but the reviewer keeps requiring an APPROVE marker on resume, causing repeated failure.Relevant code paths:
internal/reviewer/runner.go:2104-2134— clean summary handling requires an APPROVED marker when clean policy is APPROVEinternal/reviewer/runner.go:2144+— publish verifies clean marker policylooper review submitpath surfaces GitHub 422 fromghbut does not appear to downgrade own-PR approval to a comment/no-opExpected behavior
Looper should not repeatedly attempt an impossible GitHub approval on the current user's own PR.
Acceptable behavior:
author == current userbefore choosing APPROVE and use a clean COMMENT fallback with a valid Looper marker, oroutcome=cleanand mark the runskipped/clean_noop, orProposed fix
cleanReviewEvent == APPROVEbut current user owns the PR, downgrade to COMMENT or a configured fallback.Can not approve your own pull requestas a deterministic policy mismatch, not a retryable transient.