Skip to content

cursor-rules-valid

Cursor .mdc rules must have frontmatter that lets the rule activate

Severity error (auto)
Autofix auto
Since v0.19.0
Repo Types cursor
Category Cursor

Why

A Cursor rule declares when it applies in its frontmatter, and Cursor reports nothing when that declaration is wrong. A rule with malformed frontmatter is skipped; a rule whose alwaysApply is the string "true" rather than the boolean true is treated as not always-applied. In both cases the file sits in the repository looking authoritative while the agent never reads it.

.mdc frontmatter has three fields, and between them they pick one of four activation modes:

Mode Frontmatter
Always alwaysApply: true
Auto Attached globs matching the files you are editing
Agent Requested description the agent reads to decide
Manual none of the above — you type @rule-name

Manual is legitimate, so a rule with none of the three is reported at info, not as an error.

This rule flags legacy .cursorrules files that coexist with .cursor/rules/ in the same workspace.

Cursor accepts comma-separated strings or YAML lists for globs. Globs must be non-empty, relative patterns. description must be a string, and alwaysApply must be a valid boolean.

Severity

Type and shape defects are errors: malformed frontmatter, a non-boolean alwaysApply, a non-string description, a globs value that is neither a string nor a list of strings, and empty or absolute patterns.

A superseded .cursorrules is a warning. A rule that only loads via @name is info, because Manual is a legitimate mode.

Examples

Bad — the value is a string, so the rule never applies:

---
description: Repository conventions
alwaysApply: "true"
---

Badglobs are repository-relative, so an absolute pattern matches nothing:

---
globs: "src/**, /etc/hosts"
---

Good — a real boolean, and Cursor's documented comma-separated form. Each pattern is checked on its own, so a stray , , is still reported:

---
description: TypeScript conventions for the web app
globs: "**/*.ts, **/*.tsx"
alwaysApply: false
---

Components export a default function.

How to fix

  • skillsaw fix converts a boolean-looking quoted alwaysApply value ("true", "yes", "on") into a YAML boolean. "1" is left alone — reading it as true would infer intent rather than repair a spelling.
  • Malformed frontmatter needs a human: fix the YAML, or delete the frontmatter block if the rule is meant to be manual-only.
  • For a rule that never activates, decide which mode you meant and add the matching field — or leave it if you invoke it with @rule-name.

Configuration

rules:
  cursor-rules-valid:
    enabled: auto  # true | false | auto
    severity: error

Run skillsaw explain cursor-rules-valid to see this documentation and the rule's effective configuration in your terminal.