davila7/claude-code-templates · error

Failed to load skill

Error message

Failed to load skill

What it means

HTTP 500 returned by the skill dashboard's GET /api/skills/:name/file/* route when reading a skill file throws an unexpected exception (the catch-all after 'Skill not found'/'Access denied'/'File not found' checks pass but fs.readFile/fs.stat fails). It signals an I/O or permission error outside the handled cases.

Source

Thrown at cli-tool/src/skill-dashboard.js:392

      try {
        await this.loadSkillsData();
        const skillName = req.params.name;
        const skill = this.skills.find(s =>
          s.name === skillName ||
          s.name.toLowerCase().replace(/\s+/g, '-') === skillName.toLowerCase()
        );

        if (!skill) {
          return res.status(404).json({ error: 'Skill not found' });
        }

        res.json({
          skill,
          timestamp: new Date().toISOString()
        });
      } catch (error) {
        console.error('Error loading skill:', error);
        res.status(500).json({ error: 'Failed to load skill' });
      }
    });

    this.app.get('/api/skills/:name/file/*', async (req, res) => {
      try {
        const skillName = req.params.name;
        const filePath = req.params[0]; // Capture the wildcard path

        await this.loadSkillsData();
        const skill = this.skills.find(s =>
          s.name === skillName ||
          s.name.toLowerCase().replace(/\s+/g, '-') === skillName.toLowerCase()
        );

        if (!skill) {
          return res.status(404).json({ error: 'Skill not found' });
        }

View on GitHub (pinned to a0851ed10c)

Solutions

  1. Check dashboard server console for the logged 'Error loading file:' cause
  2. Fix file/directory permissions (chmod) on the skill folder
  3. Remove broken symlinks or special files from the skill directory
  4. Retry after ensuring the file still exists
Defensive patterns

Strategy: try-catch

Validate before calling

const ok = await fetch(`/api/skills/${slug}/file/${encodeURIComponent(rel)}`).then(r => r.ok);

Try / catch

try { const r = await fetch(url); if (!r.ok) throw new Error((await r.json()).error); } catch (e) { console.warn('skill file load failed', e); }

Prevention

When it happens

Trigger: GET /api/skills/<name>/file/<path> where the path passes the path-traversal check and exists, but reading fails: EACCES on a chmod-000 file, EISDIR, or the file is deleted between pathExists and readFile.

Common situations: Skill directory contains files with restrictive permissions, symlinks to unreadable targets, or race with an editor/process removing files while the dashboard is serving.

Related errors


AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28). Data as JSON: /api/errors/af4979cd5ad48bb9. Report an issue: GitHub.