davila7/claude-code-templates · warning
⚠ Error loading skill ${skillDir}:
Error message
⚠ Error loading skill ${skillDir}: What it means
loadSkillsFromDirectory iterates skill directories and parses each SKILL.md; this inner warning fires when one specific skill directory fails (missing/unreadable SKILL.md despite passing an existence check, YAML frontmatter that throws, fs.stat failure). Only that skill is skipped — the loop continues and other skills still load.
Source
Thrown at cli-tool/src/skill-dashboard.js:93
console.log(chalk.gray(` ⊘ Skipping non-directory: ${skillDir}`));
continue;
}
// Look for SKILL.md
const skillMdPath = path.join(skillPath, 'SKILL.md');
if (await fs.pathExists(skillMdPath)) {
console.log(chalk.gray(` ✓ Found SKILL.md in ${skillDir}`));
const skillData = await this.parseSkill(skillMdPath, skillPath, skillDir, source);
if (skillData) {
skills.push(skillData);
console.log(chalk.green(` ✅ Loaded skill: ${skillData.name}`));
}
} else {
console.log(chalk.gray(` ⊘ No SKILL.md in ${skillDir}`));
}
} catch (error) {
console.warn(chalk.yellow(` ⚠ Error loading skill ${skillDir}:`), error.message);
}
}
return skills;
} catch (error) {
console.warn(chalk.yellow(`Warning: Error loading skills from ${skillsDir}:`), error.message);
return skills;
}
}
async loadPluginSkills() {
const skills = [];
const pluginsDir = path.join(this.claudeDir, 'plugins', 'marketplaces');
try {
if (!(await fs.pathExists(pluginsDir))) {
console.log(chalk.gray(` ℹ Plugins directory does not exist: ${pluginsDir}`));
return skills;View on GitHub (pinned to a0851ed10c)
Solutions
- Identify the named skillDir from the warning and run `cat <skillDir>/SKILL.md` to confirm readability
- Validate the frontmatter YAML: extract the --- block and parse it with `yq` or a YAML linter
- Reinstall the skill or remove the broken directory so the scan is clean
- Fix permissions/symlinks (`ls -la`, `chmod -R u+r`) if the file exists but cannot be read
Example fix
# before --- name: my-skill # tab, unquoted colon issues --- # after --- name: my-skill ---
Defensive patterns
Strategy: try-catch
Validate before calling
const fm = fs.readFileSync(skillMd, 'utf8').match(/^---\n[\s\S]*?\n---\n/);
if (!fm) { /* skip skill, no frontmatter to parse */ } Try / catch
catch (error) {
console.warn(`Skipping skill ${skillDir}: ${error.message}`);
continue; // per-skill failure must not abort the directory scan
} Prevention
- Lint SKILL.md frontmatter with yq in CI
- Avoid tabs and unquoted colons in frontmatter
- Install/uninstall skills via the CLI, not manual file moves
When it happens
Trigger: Calling loadSkillsFromDirectory on a skills dir where one subdirectory contains a SKILL.md that is unreadable (permissions), is a broken symlink, has frontmatter yaml.load throws on (e.g. duplicate keys with certain yaml lib configs), or where fs.stat/readFile race with the file being deleted mid-scan.
Common situations: A skill was partially installed or uninstalled while the dashboard was loading; broken symlinks in a dotfile-managed skills directory; SKILL.md with invalid YAML frontmatter (tabs, unquoted special characters); skills dir synced from another OS with lost read permissions.
Related errors
- Claude Code projects directory not found at ${this.projectsD
- Warning: Error loading plugins from marketplace ${marketplac
- Warning: Error loading skills from ${skillsDir}:
- Warning: Error parsing skill ${skillDirName}
- No files were copied from Cloudflare component directory
AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28).
Data as JSON: /api/errors/278f98f37c0a397f.
Report an issue: GitHub.