Today’s idea: a CODEOWNERS file is a routing table for code review — and the two things most people get wrong about it are the rule order and what it actually enforces.
The Routing Table
Drop a file at .github/CODEOWNERS and GitHub starts matching every pull request’s changed files against it, auto-requesting review from whoever owns the matching paths. Here’s the shape, straight from an infrastructure monorepo:
# Routing table for reviews — last match wins, so broad rules go first.
# Default: platform team sees everything
* @theconveyor/platform-team
# Store-edge manifests — the edge crew owns these
/k8s/store-edge/ @theconveyor/edge-team
# Payment services — regulated path, leads only
/apps/payments/ @theconveyor/payment-leads
# Docs — no owner on purpose; any write-access approval counts
/docs/
Gotcha #1: Last Match Wins
Not first. Last. If a PR touches /apps/payments/checkout.tf, only @theconveyor/payment-leads gets the request — the * rule above it loses, because a later matching line overrides an earlier one.
So the file reads top-down from broad to specific: defaults at the top, overrides at the bottom. Get the order backwards and your carefully-scoped payment rule silently loses to the catch-all. (Related: ! negation and [ ] ranges from gitignore don’t work here — when you want “everyone except this path,” restructure with ordering instead.)
And that bare /docs/ line with no owner? That’s deliberate — it resets ownership, so docs changes don’t wait on anyone specific. Low friction for docs means docs actually get written.
Gotcha #2: The File Alone Enforces Nothing
Out of the box, CODEOWNERS only requests reviews. Anyone can still merge without waiting. The teeth come from one checkbox:
Settings → Branches → your main rule → Require a pull request before merging → ✅ Require review from Code Owners.
Now a PR touching the payments path cannot merge until a payment lead approves. Without that checkbox, your routing table is a suggestion box.
The Other 60 Seconds
Three more things that bite people on day one:
- Owners need write access — including teams, explicitly, even if every member already has it individually.
- PRs use the base branch’s file. Adding yourself as an owner inside your own PR does nothing until it merges.
- Draft PRs don’t trigger requests. Reviewers get pulled in when you mark it ready for review.
That’s the whole idea: a five-line routing table, ordered broad-to-specific, plus one checkbox to make it real.
Want the full story — richer patterns, a hands-on lab, branch-protection via the API, and the troubleshooting table? The deep-dive has you covered: GitHub CODEOWNERS: Who Owns What in Your Repo.
Happy automating!