Problem (one or two sentences)
SKILL.md frontmatter parsing fails silently when the description field contains unescaped double quotes (e.g., "TDD", "test-driven development"), causing gray-matter/js-yaml to throw a YAMLException. The error message shown is misleading: "missing required 'name' field" — but the name IS present; it just couldn't be parsed because of the YAML syntax error.
Context (who is affected and when)
Affects any user or AI creating skills via the UI (createSkill tool), skill-writer mode, or manual file creation when the description contains double quotes. The skill silently fails to load — no visible indication in the Skills UI that parsing failed (only shown in Developer Tools console). This is a UX issue because users have no way to discover the real error without opening DevTools.
Reproduction steps
- Create a skill file at
~/.roo/skills/test-skill/SKILL.md with this content:
---
name: test-skill
description: Use when implementing features. Triggers on: "TDD", "test-driven development"
---
# Test Skill
Instructions here.
- Open Zoo Code → Settings → Skills tab
- The skill does not appear in the list (even though
SKILL.md exists)
- Check Developer Tools console (
Help → Toggle Developer Tools) — see:
[Extension Host] Skill at <path> is missing required 'name' field
Programmatic reproduction:
cd /c/work/Zoo-Code
node -e "const matter = require('./node_modules/.pnpm/gray-matter@4.0.3/node_modules/gray-matter'); const fs = require('fs'); const content = fs.readFileSync('C:/Users/eason/.roo/skills/test-driven-development/SKILL.md', 'utf-8'); console.log(JSON.stringify(matter(content).data, null, 2));"
Output:
YAMLException: incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line at line 3, column 128
Expected result
Either:
- The skill loads successfully (gray-matter handles unescaped quotes gracefully), OR
- A clear error message explains the YAML parsing failure and points to the exact issue (e.g., "description contains unescaped double quotes")
Actual result
The skill silently fails to load. The console shows a misleading error: missing required 'name' field even though the name IS present in the frontmatter. Users/AI have no way to discover the real cause without opening DevTools.
Variations tried (optional)
- Wrapping description in single quotes (
description: 'Use when ... "TDD" ...') — works ✅
- Using backticks instead of double quotes (
Triggers on: \TDD``) — works ✅
- Removing all quotes from description — works ✅
App Version
Current main (v3.58.x+)
API Provider
Not Applicable / Other
Relevant logs or errors
[Extension Host] Skill at C:\Users\eason\.roo\skills\test-driven-development is missing required 'name' field
Root cause: In src/services/skills/SkillsManager.ts line 102-115, when matter(fileContent) throws a YAML parsing error (from js-yaml@3.14.1), it's caught by the outer try/catch block at line 173. The specific YAML syntax error is lost — only "missing required 'name' field" is logged.
Proposed approach
Option A: Separate gray-matter parsing error (recommended)
In loadSkillMetadata(), catch the matter() parse error separately before checking fields:
// Before (line ~102-115)
const fileContent = await fs.readFile(skillMdPath, "utf-8")
const { data: frontmatter, content: body } = matter(fileContent)
if (!frontmatter.name || typeof frontmatter.name !== "string") {
console.error(`Skill at ${skillDir} is missing required 'name' field`)
return
}
// After
try {
const fileContent = await fs.readFile(skillMdPath, "utf-8")
let parsedResult
try {
parsedResult = matter(fileContent)
} catch (parseError) {
console.error(`Failed to parse SKILL.md at ${skillDir}: YAML syntax error - ${parseError.message}`)
return
}
const frontmatter = parsedResult.data
if (!frontmatter.name || typeof frontmatter.name !== "string") {
console.error(`Skill at ${skillDir} is missing required 'name' field`)
return
}
// ... rest of validation
} catch (error) {
console.error(`Failed to load skill at ${skillDir}:`, error)
}
Option B: Auto-wrap description in createSkill() tool
In the handleCreateSkill method, automatically wrap the description value in single quotes if it contains double quotes or other special YAML characters. This prevents the issue for skills created via the UI tool.
Trade-offs / risks
- Option A: Minimal risk — only changes error message clarity. No behavior change for valid SKILL.md files.
- Option B: Could introduce unexpected formatting (e.g., single quotes in description might look odd). Requires careful escaping logic.
- Both options are backward-compatible — existing valid skills continue to work.
Related
N/A — new issue.
Problem (one or two sentences)
SKILL.md frontmatter parsing fails silently when the
descriptionfield contains unescaped double quotes (e.g.,"TDD","test-driven development"), causing gray-matter/js-yaml to throw a YAMLException. The error message shown is misleading: "missing required 'name' field" — but the name IS present; it just couldn't be parsed because of the YAML syntax error.Context (who is affected and when)
Affects any user or AI creating skills via the UI (
createSkilltool), skill-writer mode, or manual file creation when the description contains double quotes. The skill silently fails to load — no visible indication in the Skills UI that parsing failed (only shown in Developer Tools console). This is a UX issue because users have no way to discover the real error without opening DevTools.Reproduction steps
~/.roo/skills/test-skill/SKILL.mdwith this content:SKILL.mdexists)Help → Toggle Developer Tools) — see:Programmatic reproduction:
Output:
Expected result
Either:
Actual result
The skill silently fails to load. The console shows a misleading error:
missing required 'name' fieldeven though the name IS present in the frontmatter. Users/AI have no way to discover the real cause without opening DevTools.Variations tried (optional)
description: 'Use when ... "TDD" ...') — works ✅Triggers on: \TDD``) — works ✅App Version
Current main (v3.58.x+)
API Provider
Not Applicable / Other
Relevant logs or errors
Root cause: In
src/services/skills/SkillsManager.tsline 102-115, whenmatter(fileContent)throws a YAML parsing error (from js-yaml@3.14.1), it's caught by the outer try/catch block at line 173. The specific YAML syntax error is lost — only "missing required 'name' field" is logged.Proposed approach
Option A: Separate gray-matter parsing error (recommended)
In
loadSkillMetadata(), catch the matter() parse error separately before checking fields:Option B: Auto-wrap description in
createSkill()toolIn the
handleCreateSkillmethod, automatically wrap the description value in single quotes if it contains double quotes or other special YAML characters. This prevents the issue for skills created via the UI tool.Trade-offs / risks
Related
N/A — new issue.