You wrote a careful rule telling Cursor to prefer TypeScript, avoid any, and never inline styles, but the next generation does all three. The file is sitting in the repo and the model acts like it does not exist.
Fastest fix (as of June 2026): the single most common cause is a YAML frontmatter error in a .cursor/rules/*.mdc file. If the frontmatter has any mistake (missing closing ---, globs not written as a list, True instead of true), Cursor silently skips the whole file with no warning. Open the rule, fix the frontmatter, then start a new Agent chat and re-test. If you are still on the legacy single-file .cursorrules, that format is deprecated (since Cursor 0.43) and only loads in some modes. Migrating to .cursor/rules/*.mdc is the durable fix.
This article walks the rule-loading order, the four rule activation types and their exact menu labels, how to confirm a rule actually reached the model, and how to migrate cleanly between the two formats.
The four rule types (and why each one silently fails)
Cursor’s rules UI (Cursor Settings > Rules, Commands) offers four activation types in a dropdown. Each fails differently, so knowing which type you wrote is half the diagnosis.
| Type (UI label) | When it loads | Frontmatter shape | Typical silent-fail cause |
|---|---|---|---|
| Always Apply | Every chat/Agent session | alwaysApply: true | Frontmatter syntax error, or file is .md not .mdc |
| Apply to Specific Files (Auto Attached) | When a file matching globs is open or referenced | alwaysApply: false + globs: list | Glob does not match the open file path |
| Apply Intelligently (Agent Requested) | Agent reads the description and decides | alwaysApply: false, no globs, has description | Vague/empty description, so the agent never picks it |
| Apply Manually | Only when you type @rule-name | no globs, alwaysApply: false | You expected it to auto-load; it never does |
Common causes
1. Frontmatter YAML syntax error (the #1 cause)
If the frontmatter at the top of an .mdc file has any YAML error, Cursor skips the file entirely with no log, no warning, and no red squiggle. The three that bite people most:
- Missing the closing
---line, so the whole file is treated as body text. globswritten as a single string instead of a YAML list.True/Falsecapitalized. YAML booleans must be lowercasetrue/false.
How to judge: open the .mdc file and confirm it has a clean opening and closing --- block, that globs is a list, and that booleans are lowercase. A valid block looks like this:
---
description: General coding conventions for this repo
globs:
- "src/**/*.ts"
alwaysApply: false
---
2. File is .md, not .mdc
A plain .md file dropped into .cursor/rules/ is ignored by the rules system because it has no frontmatter slot. Project rules must use the .mdc extension.
How to judge: ls -la .cursor/rules/. Any rule ending in .md (not .mdc) is dead weight.
3. File at the wrong path
Legacy .cursorrules must sit at the repo root next to package.json; inside src/ or apps/web/ it is ignored. New-format .mdc files must live under a .cursor/rules/ directory. Nested folders are supported (for example .cursor/rules/frontend/components.mdc), but the .cursor/rules root must exist.
How to judge: run ls -la .cursorrules .cursor/rules/ 2>/dev/null at the repo root. If neither exists at the root, that is the issue.
4. Deprecated single-file .cursorrules
The single-file .cursorrules at the repo root is deprecated as of Cursor 0.43. It still loads for now, but it does not get the per-glob scoping or the type dropdown, and Cursor’s own /create-rule command writes the new .mdc format. If a project has both .cursorrules and .cursor/rules/, both are read and merge in an order you cannot control.
How to judge: if both exist, migrate to .cursor/rules/*.mdc and delete .cursorrules.
5. Glob scoped to a path the current file does not match
An Apply to Specific Files rule with globs: ["src/api/**/*.ts"] only attaches when a file matching that pattern is open or referenced in the prompt. Editing src/components/Button.tsx, or asking a general question like “how should I structure my components?” with no file in context, will not fire it.
How to judge: open a file that the glob should match and check whether the rule shows up in the chat context panel. If it does not appear, the glob does not match that path.
6. Workspace (project) rules vs user rules collision
Rules merge in a fixed precedence: Team Rules, then Project Rules, then User Rules, with earlier sources winning on conflict. Cursor Settings > Rules, Commands holds user-level rules; your repo holds project-level rules. If a user-level rule contradicts your project file, the merged prompt can quietly drop your project guidance.
How to judge: open Cursor Settings > Rules, Commands and skim the user-level text. Anything contradicting your project file is a suspect.
7. Too many alwaysApply: true rules
Every Always Apply rule is injected into the system prompt of every request. Stack 10+ of them and they crowd out real context, and the model produces average output that partially violates most of them. This reads as “rules ignored” even though they all technically loaded.
How to judge: count your Always Apply rules. As a rule of thumb keep only 1-2 always-on; everything else should be glob-scoped.
8. Edited mid-chat without refreshing
After editing a rule you usually need a new chat for it to load. An existing chat keeps the system prompt it started with.
How to judge: did you change rules during the same chat? Start a fresh Agent thread and re-test.
Before you start
- Confirm your Cursor version:
Cursor > About. Anything from 0.43 onward treats.cursorrulesas legacy and prefers.cursor/rules/*.mdc. - Note which surface you are using (Agent, Composer, Inline Cmd+K). The
.mdcformat loads across Chat, Composer, and Agent; legacy.cursorrulesdoes not reach every surface, and Inline Cmd+K has the least file-path context, so glob-scoped rules are weakest there. - Commit before changing rules so you can bisect which rule caused which behavior.
Information to collect
- Output of
find . -maxdepth 4 -name '.cursorrules' -o -path '*/.cursor/rules/*'. - Full contents of every rule file in the repo, including frontmatter.
- The user-level text from
Cursor Settings > Rules, Commands. - The exact prompt and the file path that was open when the rule should have applied.
- A screenshot of the chat context panel showing which rules attached.
Step-by-step fix
Step 1: Confirm the rule actually reached the model
Two checks, fastest first.
Context panel: open a file the rule should apply to and look at the chat context panel. If the rule is active, it appears there. If it does not appear, the file never loaded (skip to Step 2).
Canary probe: add a canary line to the top of the rule body (below the frontmatter):
CANARY: If you read this rule, start your next reply with the word PINEAPPLE.
Save, open a new Agent chat, and ask anything. If the reply starts with PINEAPPLE, the rule loaded. If not, the file is not reaching the model. Stop debugging behavior and debug loading first.
Step 2: Validate the frontmatter before anything else
Open the .mdc file and verify, in order:
- The opening
---is the very first line, and there is a matching closing---. - Booleans are lowercase:
alwaysApply: trueoralwaysApply: false. globsis a YAML list, not a bare string.- The file extension is
.mdc, not.md.
A single broken character here is the most common reason a rule is “ignored.” Fix it, then re-run the canary in a new chat.
Step 3: Move the file to the correct location
For the new format (recommended):
mkdir -p .cursor/rules
git mv .cursorrules .cursor/rules/general.mdc
Then add valid frontmatter at the very top of general.mdc:
---
description: General coding conventions for this repo
alwaysApply: true
---
For the legacy single-file format, if you are keeping it for now, it must be at the repo root:
git mv src/.cursorrules .cursorrules
git commit -m "move cursorrules to repo root"
Step 4: Pick exactly one format
Keep both .cursorrules and .cursor/rules/ and you get an unpredictable merge. Migrate to .cursor/rules/*.mdc and delete the legacy file. The new format is the only one that gets the type dropdown, per-glob scoping, and long-term support, and it is what Cursor’s /create-rule command and Cursor Settings > Rules, Commands > + Add Rule produce.
Step 5: Choose the right activation type
Match the rule’s job to its frontmatter:
# Always Apply — global conventions, use sparingly (1-2 total)
---
description: TypeScript and styling conventions
alwaysApply: true
---
- Prefer TypeScript over JavaScript.
- Never use `any`. Use `unknown` and narrow.
- Never inline styles. Use Tailwind classes or CSS modules.
# Apply to Specific Files — the workhorse; loads when a matching file is in context
---
description: API route conventions
globs:
- "src/api/**/*.ts"
- "src/pages/api/**/*.ts"
alwaysApply: false
---
- API handlers return `Response` objects, not Express-style res.json().
- Wrap handlers in `withErrorHandler` from src/utils/api.ts.
- Validate input with Zod before any DB call.
For an Apply Intelligently rule, set alwaysApply: false, omit globs, and write a sharp one-line description so the agent can decide when it is relevant.
Step 6: Reload the rule in a fresh chat
After every rule change:
- Save the file.
- Open a new Agent / chat thread (do not reuse the open one).
- Re-run the canary probe from Step 1.
Existing chats keep their original system prompt; only new chats see the updated rule.
How to confirm it’s fixed
- The canary probe (Step 1) returns PINEAPPLE in a fresh chat.
- The rule shows up in the chat context panel when you open a file it should apply to.
- Re-run the original failing request. The model now respects the rule.
- A teammate cloning the repo sees the same behavior, confirming the rule is version-controlled and not in personal settings.
Long-term prevention
- Keep rules under version control in
.cursor/rules/at the repo root, never only in user settings. - Keep only 1-2 Always Apply rules; scope everything else with globs so it loads only when relevant.
- Split rules by domain into separate
.mdcfiles (api, frontend, testing) rather than one giant file. - Add a CI check that fails if both
.cursorrulesand.cursor/rules/exist on the same branch. - Lint frontmatter in CI (closing
---,globsas a list, lowercase booleans) so a typo never silently disables a rule again.
Common pitfalls
- A YAML typo in frontmatter that disables the file with zero feedback.
- Saving a rule as
.mdinstead of.mdc. - Editing rules but never opening a new chat, so the old system prompt sticks.
- Writing huge rule files (5000+ tokens) that crowd out real context.
- Negative-only rules (“never do X”) with no positive guidance (“do Y instead”), so the model reverts to defaults.
- Editing the file inside a Docker volume that does not sync back to the host path Cursor reads from.
FAQ
Q: Is .cursorrules dead?
A: It is deprecated (since Cursor 0.43) but still read as of June 2026. It does not get the type dropdown or per-glob scoping, and it does not load on every surface. Migrate to .cursor/rules/*.mdc when you can.
Q: My rule has no syntax errors but still does not load. Why?
A: Almost always a glob mismatch. Temporarily set alwaysApply: true. If the rule now works, the content is fine and your globs pattern was not matching the open file, so the issue is the glob, not the rule.
Q: Do rules count against my context window? A: Yes. Always Apply rules are prepended to the system prompt on every request. Glob-scoped rules only cost tokens when a matching file is in context. Keep always-on rules tight (under ~2000 tokens combined) so they do not crowd out real code.
Q: Do .cursor/rules/*.mdc files sync to my Cursor account?
A: No. They live in your repo and travel through git. Only the user-level rules in Cursor Settings > Rules, Commands are tied to your account.
Q: Can Inline Cmd+K read rules? A: Partially. Cmd+K reliably honors Always Apply rules but has limited file-path context, so glob-scoped rules are weak there. Use the Agent or Composer surface for glob-scoped rules.
Related
- Cursor generates duplicate logic
- Cursor suggestions ignore conventions
- Cursor config conflict
- Cursor missed project context
- Cursor context panel missing files
External references: Cursor Rules docs
Tags: #Cursor #ide #Troubleshooting