A GitHub pull request touches an owned path but no code owner was requested. How do you debug it?
answer
- Resolution has stages — check them in order
- Which branch is the file read from?
- A view lists invalid entries
- Write access, granted to the team
- Drafts and self-authored PRs behave differently
basics
~20 sWork down the resolution chain: is the CODEOWNERS file in a valid location on the pull request's base branch, is the errors view clean, do the named owners have write access, does the pattern really match the path, is a later rule overriding it, and is the pull request still a draft.
solid answer
~50 sDebug it in the order GitHub resolves it. **File**: it must be named `CODEOWNERS`, sit in `.github/`, the root or `docs/`, and — critically — exist on the pull request's **base** branch, since a copy added on the head branch does not count. **Validity**: open the file on GitHub and read the CODEOWNERS errors view; unknown users, teams from another organization, and owners lacking write access are flagged there and own nothing. Remember a team needs write access granted to *the team*, not merely to its members. **Matching**: check the pattern against the actual path — `docs/*` matches only direct children, and a leading slash anchors to the root. **Precedence**: the last matching line wins, so a broad rule appended lower in the file may have stolen ownership. **State**: draft pull requests do not auto-request code owners, and GitHub never requests the author, so a path owned only by the author looks unowned.
go deeper
Know the first two checks: the file must be in a valid location, and it must already exist on the branch the pull request targets. Most reports stop right there.
Walk the resolution chain out loud — location, base branch, errors view, pattern match, last-match precedence — and explain why an invalid line fails silently instead of erroring.
Show that you separate 'nobody was requested' from 'nobody was required', check draft state and self-authored paths, and audit write access at the team level rather than the member level.
Treat silent failure as the real risk: put controls around the ownership map itself — the file owned and reviewed, offboarding and team renames as triggers to re-validate, single-owner paths eliminated.
## Debug along the resolution chain "No code owner was requested" has a small number of causes, and they sit at distinct stages of how GitHub resolves ownership. Walking them in order turns a confusing report into a two-minute check. ### 1. Is there a file GitHub will read? The file must be named `CODEOWNERS` exactly and live in `.github/`, the repository root, or `docs/`. GitHub searches those in that order and uses the first one found — so a second copy elsewhere is ignored, and a copy in an arbitrary directory is inert. If someone "added CODEOWNERS" to `src/` or named it `codeowners.txt`, nothing downstream will ever work. ### 2. Is it on the base branch? Ownership is resolved from the copy on the branch the pull request targets, not the branch carrying the changes. This catches people constantly: a pull request that *introduces* the rules is judged by the base branch's older file, so the new owners are not requested on that pull request. The same applies to long-lived release branches that never received the file — pull requests targeting them have no code owners at all, however complete `main`'s file is. ### 3. Are the entries valid? Browse the file on GitHub: invalid lines are surfaced in a CODEOWNERS errors view, and a pull request editing the file is annotated with the same problems. Typical entries that resolve to nobody: - a username with a typo, or an account that has left the organization; - a team written without its organization (`@backend` instead of `@my-org/backend`); - a team from a different organization than the one owning the repository; - an owner without **write** access — and for a team, write access must be granted to the team on that repository, not merely held individually by its members; - a malformed pattern. An invalid line does not break the rest of the file; it just silently owns nothing, which is precisely why teams believe a path is covered when it is not. ### 4. Does the pattern match this path? Patterns are gitignore-style, and the near-misses are predictable. `docs/*` matches files directly inside `docs` but not inside `docs/api/`. A leading slash anchors to the repository root, so `/build/` will not match `packages/app/build/`. A trailing slash covers a directory and everything beneath it. Compare the pattern against the exact changed path from the pull request's Files changed list rather than against the directory you had in mind. ### 5. Is a later rule winning? GitHub keeps the **last** matching rule for each file, and ownership never accumulates. A catch-all appended at the bottom of a long file overrides every specific rule above it — the classic regression after someone "just added one line". Read the file bottom-up for the first line that matches the path in question; that is the winner. ### 6. Is the pull request in a state that requests reviewers? Draft pull requests do not automatically request code owners; the requests go out when the pull request is marked ready for review. And GitHub never requests the author to review their own pull request, so if the only owner of the changed path is the person who opened it, no request appears — and, where code owner review is required, the pull request is blocked with no one able to satisfy it except another owner or a bypass. Also check whether the owner was already a requested reviewer or has already reviewed; GitHub will not duplicate an existing request, which can look like the rule failing. ### 7. Separate "not requested" from "not required" Finally, distinguish two complaints. If owners are requested but the pull request merges without them, the file is fine and the missing piece is enforcement: required review from Code Owners on the target branch, plus a rule requiring a pull request in the first place, plus a bypass list that is not wider than intended. If nobody is requested at all, the problem is in steps 1–6. ## Preventive habits Own `/.github/CODEOWNERS` in the file itself so ownership changes are reviewed. Check the errors view after any edit that renames a team or offboards a person, because both fail silently. Keep the file ordered broad to narrow and treat an appended broad line as a defect in review. And prefer teams to individuals, which removes the single-owner-is-the-author deadlock entirely.
- The owning team exists and every member has write access, yet the team is never requested. Why?Because the permission has to be granted to the team on that repository, not held individually by its members. A team that has never been added to the repository is not a valid code owner and is reported in the CODEOWNERS errors view. Adding the team with at least write permission fixes it.
- How would you catch a broken CODEOWNERS file before someone notices at review time?Read the CODEOWNERS errors view after every edit, and own the file itself so changes to it get reviewed. Treat offboarding and team renames as triggers to re-check, since both turn valid entries into silent no-ops. Some teams additionally open a throwaway pull request touching a representative path to confirm the expected owners are requested.
- Owners are requested but the author merges anyway. What is missing?Enforcement, not the file. The target branch needs required review from Code Owners, and it must also require a pull request before merging — otherwise a direct push skips the check entirely. Then audit the bypass actors and administrator handling, since anyone in that set can merge without owner approval.
saying these in an interview costs you the question
- Looking at the head branch's CODEOWNERS instead of the base
- Ignoring the CODEOWNERS errors view
- Assuming members' write access covers the team
- Forgetting drafts do not auto-request owners
- Not checking whether a later rule overrides the intended one