Safeguard
Developer Tools•

CODEOWNERS paths after moving a repo into a monorepo subdirectory

A CODEOWNERS file copied into a monorepo subdirectory stops working. Rewrite the paths, check team write access, and test with a draft pull request.

Safeguard Security Team
3 min read

A CODEOWNERS file copied from an old repo into a monorepo subdirectory is ignored, because GitHub reads it only from the root, .github/ or docs/ of the repository. Merge each team's entries into one root file with every path prefixed by its new directory, then confirm the teams have write access.

Why the old file goes quiet

GitHub's documentation says to create the CODEOWNERS file in the .github/, root, or docs/ directory of the repository, and if files exist in more than one location it uses the first one it finds, in that order. A file at services/payments/CODEOWNERS is just a file. Nobody is requested for review because of it, and nothing warns you.

Patterns also change meaning. A line such as /src/ @payments-team anchors to the repository root. After the move, the code lives at services/payments/src/, so the pattern matches nothing.

How to translate the entries

Old repo patternMonorepo pattern
*/services/payments/
/src//services/payments/src/
*.sql/services/payments/**/*.sql
/docs//services/payments/docs/

The default * line from each old repo becomes a directory entry, not a global one. Keep a real catch-all at the top of the new file so unowned paths still have a reviewer, and remember that the last matching pattern takes precedence, so specific entries go below it.

Steps

  1. List each source repo's CODEOWNERS and its owners.
  2. Write the new root file with one block per imported directory, prefixed paths, and the original owners.
  3. Check that every team named is visible and has explicit write access to the new repository. The docs state that users and teams must have write access, even if team members already have it another way. A team without it will not be assigned.
  4. Look for syntax that does not work. The docs list gitignore rules that CODEOWNERS ignores: escaping a leading #, negating with !, and character ranges in square brackets.
  5. Protect the file itself. The docs say that to protect a repository fully you also need an owner for the CODEOWNERS file, and recommend placing it in .github/ with the repository owner on /.github/.
  6. Turn on "Require review from Code Owners" in branch protection or a ruleset.
  7. Test with a draft pull request touching one file per directory.

One more catch: the docs say code owners are not automatically requested to review draft pull requests, so test with a ready-for-review one.

Watch the size and the gaps

The file must stay under 3 MB or it will not load. For many services, use wildcards to shorten it. Then look for directories nobody owns, which our guide on finding repos nobody owns with CODEOWNERS explains, and for the pattern traps in CODEOWNERS file pitfalls: last match wins.

Ownership data is also useful beyond reviews. Safeguard's policies and gates can enforce checks on pull requests, and they work better when the ownership map is right.

Quick check

Can I keep one CODEOWNERS file per service folder?

Not on GitHub. It reads one file per branch from the root, .github/ or docs/. GitLab supports its own CODEOWNERS format, so check that platform's docs if you use it.

Does one approval from any owner on a line suffice?

Yes. When code owner review is required, an approval from any listed owner on the matching line satisfies it.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.