10 common SKILL.md anti-patterns and how to fix them
Most low-scoring SKILL.md files share the same handful of authoring patterns. None of them are about quality of the underlying idea — they're about communication. The fixes are usually small. Below is the top-10 list, ranked by frequency in the ~57% of catalog skills that fail to clear the daily_eligible threshold, with concrete before/after pairs.
The phantom description+8 fix
Description under 80 characters. Claude reads this to decide whether to invoke the skill — too short means the model has nothing to pattern-match against.
description: Helps with refactoring code.description: Reviews TypeScript codebases for unused exports, circular imports, and dead-code paths. Use after running tsc to catch the type-system-invisible cleanup opportunities.Why: the quality rubric awards +13 for descriptions ≥200 chars. Going from 40 → 200 = +9 alone, plus 5 vocabulary-diversity bonus = +14 swing.
No "When NOT to use" section+16 fix
The single highest-leverage edit in the entire rubric. Skills that name their out-of-scope boundary score up to 16 points more than identical skills that don't.
## When NOT to use this skill
Skip this skill if:
- You need a one-off ad-hoc analysis — out of scope.
- You're working with a binary file (PDF, image) — not for those formats.
- You want speculative refactoring suggestions — use the related code-review skill instead.Why: the rubric counts distinct anti-trigger patterns ("out of scope", "not for", "use the X instead"), capped at 4 × 4 = 16 points. Above section hits all four.
"This skill..." opening sentences−5 penalty
Starting every paragraph with self-referential framing instead of content. The rubric subtracts 5 points if the body contains "this skill", "a skill that", "use this skill", or "this is a skill".
Why: Claude already knows it's a skill — repeating "this skill" wastes tokens. The fix is just to delete the phrase; usually the sentence reads better.
Frontmatter that's just name + description+8 fix
The minimum legal frontmatter parses, but the rubric rewards additional metadata: model, tags, license, allowed-tools, argument-hint, category, version.
---
name: my-skill
description: Does a thing.
------
name: my-skill
description: Does a thing.
model: claude-3-5-sonnet
tags: [type:audit, lang:python]
license: MIT
allowed-tools: ["read", "bash"]
argument-hint: "<path-to-file>"
version: 1.0.0
---Why: 5 extra keys × 1.5 = +8 points. Most are useful to downstream consumers anyway; you're not adding clutter.
Body under 500 characters+5 to +12 fix
Bodies under 500 chars score 3 on the name+body+interface axis. 500-2,000 chars score 8. ≥2,000 chars score 15. The jump from 200 → 800 chars is +5; 500 → 2,000 chars is +7.
Why: longer bodies give Claude more context for when the skill applies + how it should behave. The point boost is incidental; the user-experience improvement is the real win.
Pricing-less wrappers for paid APIs+10 fix
If your skill wraps OpenAI / Anthropic / Stripe / AWS — anything where invoking the skill costs money — declare the pricing.
## Pricing & quota
| Provider | Free tier | Paid tier | Rate limit |
|---|---|---|---|
| Foo | 100/day | $5/1k requests | 60 rpm |Why: the pricing-disclosure axis is 0-10. A dollar-bearing table OR explicit rate-limit/quota keywords trigger the points. Helps the user too — opaque pricing is a real adoption blocker.
Name === description+5 fix
Skills where the name is just a restatement of the description (or vice versa).
name: code-reviewer + description: Reviews code.name: code-reviewer + description: Audits TypeScript codebases for unused exports, type-system gaps, and SOLID-principle violations. Outputs a categorised punch-list with fix suggestions.Why: the rubric rewards distinct name + distinct description with +5. Two identical-info fields waste the affordance.
Vague trigger languageretention fix
Descriptions like "helps with X" don't tell Claude WHEN to invoke. Use action verbs + concrete signals.
Why: Claude needs a trigger pattern. "Use when X happens" sentences map directly into the model's decision boundary. Doesn't change the rubric score, but it changes whether the skill gets invoked at the right times.
No example invocation block+3 fix
The body should include at least one example showing what the user types and what the skill outputs.
## Example
User: review-this src/auth.ts
Skill output:
1. Unused export: `legacyLogin()` — line 14, no imports found
2. Circular import: src/auth → src/user → src/auth — break via interface
3. Missing return type: `async function signOut()` — should be Promise<void>Why: +3 on the interface axis. More importantly, examples are the single best documentation format. Anyone reading the SKILL.md can immediately see if the skill matches their use case.
Missing author / source attributionpolicy fix
Doesn't directly affect the quality rubric, but it affects whether the skill appears in the new /author/ profile pages. Skills without an author: frontmatter field can't be grouped under their author's profile and miss the inbound link mass from the leaderboard articles.
author field.author: Jane Doe (or author_url: https://github.com/jdoe)Why: the catalog uses an alphanumeric-lowered display-name key to group authored skills. Skills without an author fall outside this grouping → no profile-page boost. Adding one field rolls your existing roster under /author/<your-handle>/.
How to apply this list
If you have a SKILL.md scoring under 60: anti-patterns 1, 2, 4, 5 typically apply. ~30 min of edits usually crosses the admission threshold (50) by a comfortable margin.
If you're at 60-79: anti-patterns 2, 3, 6, 9 are the highest-leverage. The "When NOT to use" section alone (anti-pattern 2) typically lifts a 75 into the daily_eligible bucket (≥80).
If you're already in daily_eligible: anti-patterns 7-10 polish the SKILL.md without big point shifts but improve real-world invocation accuracy + profile-page integration.