Blog
Why does Copilot ignore copilot-instructions.md?
Published: November 6, 2026
Most of the time Copilot never received the file. Inline suggestions do not use instructions at all. Each Copilot surface reads a different set of files, a setting can switch them off, and a path-specific file with a bad applyTo never matches. When the file did arrive, it is guidance the model weighs, not a rule Copilot enforces.
This note takes each cause, shows how to check for it, and says which fix holds. The facts are from GitHub's repository instructions docs, its support matrix, and VS Code's custom instructions guide, read 2026-11-06. What the file itself should contain is in copilot-instructions.md.
How do I check whether Copilot used my instructions?
Before you rewrite a line, find out whether Copilot saw it. Each surface has its own check:
- Copilot Chat (GitHub.com and VS Code): expand the References list at the top of the answer and look for
.github/copilot-instructions.md. VS Code's docs are careful about what that proves: it checks inclusion, not compliance. - VS Code, in detail: the Chat Debug view shows the request that was sent, including which instruction files were attached. Turn logging on before you reproduce the problem.
- Copilot CLI:
/instructionslists the instruction files the session found and whether each one loaded. - Code review: Copilot reads instructions from the head branch of the pull request, the one with your changes. So you can edit the file in the same pull request and request a new review to test it.
Why is Copilot not reading copilot-instructions.md?
- You are looking at inline suggestions. The grey text that appears as you type does not use custom instructions. VS Code's docs say so directly. Instructions reach Chat, agent mode, the cloud agent, the CLI and code review, each in its own way.
- That surface does not read that file. The support matrix differs by product. Copilot Chat on GitHub.com reads repository-wide and organization instructions but not
.github/instructions/*.instructions.md: on GitHub.com, path-specific files reach only the cloud agent and code review. Code review in VS Code and Visual Studio reads only the repository-wide file. In Eclipse, code review reads none. - A setting is off. In VS Code,
github.copilot.chat.codeGeneration.useInstructionFilescontrolscopilot-instructions.md,chat.includeApplyingInstructionscontrols matching.instructions.mdfiles, andchat.useAgentsMdFilecontrols the rootAGENTS.md. On GitHub.com, a repository admin can turn off “Use custom instructions when reviewing pull requests” under Settings, Copilot, Code review. - The
applyTonever matches. There is no default pattern. The glob is relative to the repository root, not to.github/instructions/, soapplyTo: "*.ts"matches only TypeScript files at the root; you want"**/*.ts". In VS Code, a file with neitherapplyTonor adescriptionis only attached when you add it by hand. - It is a nested
AGENTS.md. VS Code reads the one at the workspace root. Discovering nested files is experimental and off by default, behindchat.useNestedAgentsMdFiles. The cloud agent does readAGENTS.mdanywhere in the repository; how each agent handles these files is in AGENTS.md vs CLAUDE.md. - Your Copilot CLI is old. Two loading bugs were fixed this year. Before v1.0.36 the CLI skipped every instruction file under
.github/when that folder was gitignored, with nothing in the logs (#1981). The user-level~/.copilot/copilot-instructions.mdwas listed but not loaded (#2179, #1827). Both are closed as fixed. Update before you debug further.
Why does Copilot ignore instructions it loaded?
Because they are text in the prompt, and the model weighs them against everything else it was given. VS Code's docs say it plainly: instructions guide the model and do not guarantee compliance. GitHub's code review docs add that Copilot will not catch every problem. A rule that holds in most sessions can still lose to a long task.
Conflicts make it worse. GitHub gives Copilot every set of relevant instructions at once: personal first in priority, then repository, then organization, plus every path-specific file that matches. Two files that disagree both reach the model. Copilot's own system instructions count too. In #3552 (open), a repository rule said never to commit on its own; the CLI committed anyway, and its explanation pointed to a commit trailer in its system instructions. The user put the rule's hit rate at about 95% by their own estimate.
The fix for a conflict is to delete one side. A third line explaining which one wins is one more thing to weigh. For vague rules, the same docs suggest clarifying one rule, repeating the task in a new chat, and comparing what changed.
Causes, checks, and fixes
| Cause | How to check | What holds |
|---|---|---|
| Inline suggestions | Is it grey text as you type? | Use Chat or agent mode for rule-bound work |
| Surface does not read that file | GitHub support matrix, per product | Put the rule in a file that surface reads |
| Setting off | VS Code settings; repo Settings, Copilot, Code review | Turn it on |
| applyTo never matches | Is the glob relative to the repo root? | Use **/ patterns |
| Nested AGENTS.md in VS Code | chat.useNestedAgentsMdFiles | Turn it on, or move the rule to the root |
| Old Copilot CLI | /instructions, then the CLI version | Update the CLI |
| Two files disagree | Read personal, repo, org and path files together | Delete one side |
| Loaded and still not followed | References list, then the diff | A hook, a linter or CI, not prose |
How do I make Copilot always follow a rule?
Move it out of the prompt. Copilot CLI and the cloud agent run hooks from .github/hooks/*.json in the repository. A preToolUse hook runs before each tool call and can refuse it by printing JSON with permissionDecision: "deny" and a reason. If any hook denies, the call is blocked:
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "./.github/hooks/no-commit.sh",
"timeoutSec": 30
}
]
}
}A hook that crashes or exits non-zero also denies; a hook that times out lets the call through. The cloud agent runs a subset of the events. The full contract is in GitHub's hooks reference. Inline suggestions and Chat on GitHub.com have no hooks, so for those the backstop is the same as for people: a linter, a formatter and CI.
Everything else stays prose, and prose works best short and concrete: “Run pnpm test before committing”, not “test your changes”, with nothing a linter already enforces. Check your rule files runs that test on yours. The same problem in other agents is covered in why Claude ignores CLAUDE.md and why Codex ignores AGENTS.md.
Where Harbor fits
Several causes above come from one design: a set of files per product, each read by some surfaces and not others, where nothing tells you which rule reached the model. Harbor serves Copilot the decisions your team made, picking the ones that apply to the task. harbor init installs it for Copilot CLI and VS Code's agent mode (the cloud agent is not supported yet), and any MCP client can search the same facts. Answers cite the facts they used, and Harbor counts, per fact, how often it was served and how often it was cited. A cite is evidence that a rule was used, not proof that it was obeyed; the method is in served vs cited.
Questions
Why is Copilot not following copilot-instructions.md?
Usually it never received the file. Inline suggestions do not use custom instructions, each Copilot surface reads a different set of files, and in VS Code a setting can turn them off. When the file did load, it is guidance the model weighs, not a rule Copilot enforces. Check the References list on the answer first.
How do I know if Copilot used my custom instructions?
In Copilot Chat, expand the References list at the top of the answer and look for .github/copilot-instructions.md. In VS Code the Chat Debug view shows the full request, and in Copilot CLI /instructions lists which files loaded. References show the file was included, not that it was followed.
Why are my .instructions.md files not applied?
The applyTo glob is relative to the repository root and has no default, so "*.ts" only matches root files; use "**/*.ts". On GitHub.com, path-specific files reach only the cloud agent and code review, not Copilot Chat.
How do I make Copilot always follow a rule?
Put it outside the prompt. Copilot CLI and the cloud agent run hooks from .github/hooks/*.json, and a preToolUse hook can deny a tool call. For surfaces without hooks, use a linter, a formatter and CI.