If your pull request says Review required, the branch you're merging into has a protection rule (or a ruleset) that blocks merging until someone with write access approves the PR. You can't approve your own PR. So either you get the right person to review it, or, if it's your repo, you change the rule.
That's the short answer. The longer one matters because "I got an approval and it still says review required" is its own special kind of annoying.
TL;DR
- "Review required" comes from a branch protection rule or a ruleset that requires approvals.
- Only approvals from people with write access count. Yours never does.
- Stale approvals, CODEOWNERS and an open "changes requested" review are the usual reasons it won't go away.
- To find every PR stuck on this, search with
review:required, or rungh search prs --review=required.
Where does "Review required" come from?
GitHub doesn't turn this on by default. Someone on your team did, in one of two places:
- Classic branch protection: repo Settings → Branches, a rule on
main(or whatever) with "Require a pull request before merging" and "Require approvals" ticked, plus a number. - Rulesets: repo or org Settings → Rules → Rulesets, a branch ruleset with "Require a pull request before merging" and a required approvals count.
Either one puts a block in the merge box along the lines of "At least 1 approving review is required by reviewers with write access." The merge button stays grey until it's satisfied.
One thing that surprises people: on GitHub Free, protected branches only work on public repos. Private repos need Pro, Team or Enterprise. GitHub's about protected branches page has the plan details and the full list of options. So if you're hunting for the setting on a private side project and it isn't there, that's probably why.
Who can actually clear it?
An approval only counts if:
- It's from someone other than the PR author. GitHub won't let you approve your own PR.
- That person has write access (or higher) to the repo. Someone with read access can leave an approving review and it shows up in the timeline, but it doesn't count toward the requirement.
- If code owner review is required, it's from an owner of the files the PR touches.
- There are enough of them. A rule that wants two approvals is not impressed by one.
The write access part catches people on open source projects and in orgs with loose team permissions. A drive-by "LGTM" from a contributor feels nice. It doesn't unblock anything.
Why does it still say review required after someone approved?
This is the question that sends most of us to Google. Usually it's one of these.
The approval went stale
If the rule has Dismiss stale pull request approvals when new commits are pushed turned on, any push to the branch wipes existing approvals. That includes the one-line typo fix you pushed after your reviewer said "looks good, just fix the typo." Yes, really. They have to approve again.
There's a stricter version too: Require approval of the most recent reviewable push. With that on, whoever pushed last can't be the one approving that push. So if your reviewer pushes a fixup commit to your branch to save time, now somebody else has to approve.
Code owners haven't signed off
With Require review from Code Owners turned on, GitHub reads a CODEOWNERS file (in .github/, the repo root, or docs/) and requires an approval from an owner of every path the PR changes. Something like this:
# .github/CODEOWNERS
*.ts @your-org/frontend
/infra/ @your-org/platform
Touch one file under /infra/ and the platform team has to approve, no matter how many frontend people already did. The PR's reviewer list shows which owners are still pending. The CODEOWNERS docs explain the matching rules. Later lines win over earlier ones, which trips up a lot of files.
Someone requested changes
A "Changes requested" review from someone with write access blocks the merge, even if other people approved. It stays there until that reviewer approves or someone with permission dismisses their review. Once you've addressed the comments, hit the re-request review button (the circular arrows next to their name in the Reviewers sidebar) so it lands back in their queue.
You're short on approvals
The rule says 2, you have 1. Boring, but it's the answer more often than you'd expect.
How do I find every PR waiting on a review?
GitHub's search has review qualifiers that most people never touch. From the search docs:
| Qualifier | What it finds |
|---|---|
review:required | PRs that need a review before they can merge |
review:approved | PRs with an approving review |
review:changes_requested | PRs where a reviewer asked for changes |
review-requested:@me | PRs where you, or a team you're on, were asked to review |
user-review-requested:@me | PRs where you personally were asked |
reviewed-by:@me | PRs you've already reviewed |
A couple of searches worth bookmarking:
is:pr is:open author:@me review:required
is:pr is:open user-review-requested:@me archived:false
The first is "my stuff that's blocked." The second is "stuff that's blocked on me." You only really need those two.
From the terminal
The gh CLI does the same thing. gh pr list works on one repo at a time; gh search prs works across all of them:
# your open PRs, any repo, still waiting on approval
gh search prs --author=@me --state=open --review=required
# PRs waiting on your review
gh search prs --review-requested=@me --state=open
# what's blocking one specific PR
gh pr view 123 --json reviewDecision,reviewRequests
reviewDecision comes back as REVIEW_REQUIRED, CHANGES_REQUESTED or APPROVED, which is handy in scripts. A few more that save clicks:
# ask someone to review
gh pr edit 123 --add-reviewer some-username
# merge automatically once requirements are met
gh pr merge 123 --auto --squash
Auto-merge only works if the repo has Allow auto-merge turned on under Settings → General. If it's on, use it. It means you stop refreshing the PR to see if it's approved yet.
Setting up required reviews without hating them
If you own the repo, here's my opinion on the knobs:
- One approval is plenty for small teams. Requiring two on a three-person team means every PR waits for both other people, and someone is always on holiday.
- Dismiss stale approvals is worth it if people force-push big rewrites after approval. If they mostly push typo fixes, it just generates re-review busywork. Pick based on how your team actually works.
- CODEOWNERS is great for scoped areas like
/infra/or/migrations/. A*line pointing at a single person turns that person into a bottleneck. - Bypass exists, and you should know who has it. In classic rules, admins can bypass unless "Do not allow bypassing the above settings" is ticked. In rulesets, it's an explicit bypass list. If you're on that list, the merge box shows an option to merge without waiting for requirements to be met. Use it for real emergencies, not because Friday.
To see what's actually enforced on a branch without clicking through settings:
# classic branch protection (404 if there isn't any)
gh api repos/OWNER/REPO/branches/main/protection
# every ruleset rule that applies to main
gh api repos/OWNER/REPO/rules/branches/main
The second one is useful in orgs, where a ruleset set at the org level can apply to your repo without showing up in the repo's own branch settings.
If you want the bigger picture of how reviews fit into a team's day, our GitHub PR review workflow guide goes through it end to end.
The real problem is noticing the request
Required reviews usually do their job. The part that breaks is people noticing the request. Review requests arrive as notifications and emails, mixed in with CI failures, bot comments and every mention in every repo you've ever starred. If that sounds familiar, there's a whole post on too many GitHub notification emails. Then you open each PR to check its state, and suddenly you've got fourteen tabs open and no idea which one you were on. We've written about that tab problem too.
That's the gap PRFlow fills. It's a Chrome side panel that lists your open PRs across repos, with each one's review status (pending, changes requested), labels, comment count and diff size. It has filters for the two searches above: needs my review (that's review-requested:@me) and created by me, plus reviewed but not merged for PRs that got approved and then got forgotten. You keep the panel open next to whatever tab you're in, so you see the queue without going looking for it.
What it doesn't do: it won't approve anything for you, it can't bypass a protection rule, and it doesn't change your repo settings. If your PR needs a code owner's approval, PRFlow will show you it's stuck. Getting the code owner to look is still up to you. If you're comparing options, there's a roundup of Chrome extensions for code review, and more under code review.
Nudge with the re-request button, not a chat ping
When your PR is stuck on someone, use the re-request review button instead of (or as well as) messaging them. A chat message gets read once and scrolls away. A re-request puts your PR back into their review-requested:@me results, along with anything else they check. A chat message gets lost in the scroll. The re-request stays on their list until they deal with it.