You dropped .cursorrules at repo root saying “use 4-space indent, never use any.” Composer still hands you 2-space code full of any. Ask “what rules do you see?” and it says none. Usually it’s a wrong location (legacy .cursorrules vs new .cursor/rules/*.mdc), non-UTF-8 encoding, client too old for the new format, or stale rules cache.
Fix by ruling out location and format first, then verifying which rules Cursor actually loaded.
Common causes
1. File not at workspace root
Cursor only looks at the workspace root for .cursorrules. If you opened ~/code/monorepo but the rules sit at ~/code/monorepo/packages/web/.cursorrules, only opening packages/web as workspace loads them.
How to judge: bottom-left shows workspace path; ls .cursorrules must list at that root.
2. Using new .cursor/rules/*.mdc with old client
Later Cursor promoted .cursor/rules/ directory + .mdc files with frontmatter (globs / alwaysApply / agent_requested). Old clients don’t recognize this structure.
How to judge:
ls .cursor/rules/
Files present but Composer doesn’t see them = client too old.
3. Encoding isn’t UTF-8 or has a BOM
Windows Notepad defaults to UTF-8 with BOM; Cursor reading a BOM may fail to parse and fall back to no rules.
How to judge:
file .cursorrules
# expect: ".cursorrules: UTF-8 Unicode text"
# bad: ".cursorrules: UTF-8 Unicode (with BOM) text"
hexdump -C .cursorrules | head -1
# starts with ef bb bf = BOM
4. Rules cache hasn’t refreshed
After adding / editing rules, the client may serve the old version for 5-30 minutes.
How to judge: just edited, no effect; restart Cursor and it works = cache.
5. .cursor/rules/*.mdc missing trigger condition
.mdc frontmatter supports alwaysApply: true / globs: ["**/*.ts"] / description. With only a description, rules don’t auto-inject.
How to judge:
---
description: Use 4-space indent
# no alwaysApply, no globs → never injected
---
6. Rules in .gitignore / .cursorignore
Some teams .gitignore .cursorrules as personal preference and accidentally .cursorignore it too — Cursor’s own ignore makes it skip the rules file.
How to judge: git check-ignore .cursorrules / cat .cursorignore | grep cursorrules.
Before you start
- Decide which format you intend to use: legacy
.cursorrulesvs new.cursor/rules/*.mdc. Don’t mix. - Commit before editing rules so failed-load can be diagnosed against a known baseline.
- Note Cursor version; the new format needs a recent client.
Info to collect
- Cursor version (Cursor → About).
- Paths + contents of
.cursorrulesor.cursor/rules/. file .cursorrulesoutput (encoding + BOM).- Composer’s reply to “what rules are active?”
- Whether
.cursorignorecontains “cursorrules.”
Shortest fix path
“Location → format → cache.”
Step 1: Confirm the file is at workspace root
pwd # or check bottom-left workspace label
ls -la .cursorrules .cursor/rules/ 2>/dev/null
If rules are in a packages subdir, either open that subdir as workspace or move the rules to the actual root.
Step 2: Strip BOM, force UTF-8
file .cursorrules
# Strip BOM if present
sed -i.bak '1s/^\xEF\xBB\xBF//' .cursorrules
# Or in VS Code: bottom-right shows "UTF-8 with BOM" → "Save with Encoding" → "UTF-8" (no BOM)
Step 3: Verify Cursor version supports the new format
.cursor/rules/*.mdc needs at least Cursor 0.42. Cursor → Check for Updates. If stuck:
# macOS
brew upgrade --cask cursor
# Or fresh download from https://cursor.com/download
Step 4: Add trigger conditions to .mdc rules
.cursor/rules/style.mdc
---
description: TypeScript style rules
globs: ["**/*.ts", "**/*.tsx"]
alwaysApply: true
---
- Use 4-space indent
- Never use `any` — use `unknown` or specific types
- Prefer `interface` over `type` for object shapes
alwaysApply: true forces injection every time; globs auto-activates by file type.
Step 5: Force flush the rules cache
Cmd+Shift+P → "Developer: Reload Window"
Or harder — wipe workspace cache:
rm -rf ~/Library/Application\ Support/Cursor/User/workspaceStorage/<this-workspace-hash>
Step 6: Have Composer verify
In chat:
List every active cursor rule you can see right now, including their source files and any conditions on activation.
Lists rules = loaded. “No rules” = still failing.
How to verify the fix
- Composer enumerates rules content and the generated code respects them (indent / naming / imports).
- Sync repo on another machine — rules recognized too.
- Have a teammate open the same workspace and ask “what rules are active?” — consistent answer.
If it still fails
- Reduce rules to one extreme sentence like “Always begin every reply with the word HELLO.” If obeyed → rules load; behavior is a prompt problem.
- Roll back the latest Cursor upgrade or rules edit.
- Search forum.cursor.com for “cursorrules not loaded”; include Cursor version + file path + encoding.
- Grab View → Output → Cursor rules-loading logs and post to Bug Reports.
Prevention
- After adding rules, immediately ask in chat “what rules do you see?” — don’t wait to be surprised.
- Prefer new
.cursor/rules/*.mdcwith explicitalwaysApply: trueover legacy.cursorrules; more controllable. - Edit rules in VS Code / Cursor, not Notepad — avoids BOM.
- Commit team rules to git; don’t
.gitignorethem. Use user-level config for personal preferences. - After every rules edit, Cmd+Shift+P → Reload Window to bust the cache.
Related reading
- Cursor suggestions ignore conventions
- Cursor config conflicts with VS Code workspace settings
- Cursor model list out of date
- Cursor Composer made sweeping wrong edits
- Cursor generates duplicate logic
Tags: #Cursor #Troubleshooting