affaan-m/ECC · warning

WARN: - references skill directory skills/ / (not found…

Error message

WARN: ${file} - references skill directory skills/${refName}/ (not found locally)

What it means

validate-commands.js scans command/skill markdown for references to `skills/<name>/` directories and warns when the referenced skill directory does not exist in the local repo (and is not one of the reserved roots 'learned' or 'imported'). It prevents docs from pointing at skills that were renamed, deleted, or never added.

Solutions

  1. Fix the reference in the flagged file to point at an existing skill directory
  2. If the skill was renamed, update all occurrences of the old name to the new directory name
  3. If the skill should exist, add skills/<refName>/SKILL.md and register it per CONTRIBUTING.md
  4. If the reference is intentionally illustrative, move it inside a code block so the validator's contentNoCodeBlocks filter excludes it

Example fix

// before (docs/command.md)
Run the workflow described in skills/review-workflow/...
// after
Run the workflow described in skills/code-review/...
Defensive patterns

Strategy: validation

Validate before calling

const refName = 'code-review';
const valid = fs.existsSync(path.join('skills', refName, 'SKILL.md'));
if (!valid) console.warn(`skills/${refName}/ not found`);

Prevention

When it happens

Trigger: A markdown file (command, skill, or doc) contains a string matching the regex /skills\/([a-z][-a-z0-9]*)\// outside code blocks, where <name> is neither in the reservedSkillRoots set nor present in the validSkills set built from the local skills directory.

Common situations: Renaming or removing a skill without updating cross-references in commands/ or docs/; typos in a skill name inside a workflow description; contributing a doc that references a skill planned but not yet merged.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/14f68bf48be51811. Report an issue: GitHub.

Appendix: source

Thrown at scripts/ci/validate-commands.js:160

    // Check agent references (e.g., "agents/planner.md" or "`planner` agent")
    const agentPathRefs = contentNoCodeBlocks.matchAll(/agents\/([a-z][-a-z0-9]*)\.md/g);
    for (const match of agentPathRefs) {
      const refName = match[1];
      if (!validAgents.has(refName)) {
        console.error(`ERROR: ${file} - references non-existent agent agents/${refName}.md`);
        hasErrors = true;
      }
    }

    // Check skill directory references (e.g., "skills/tdd-workflow/")
    // learned and imported are reserved roots (~/.claude/skills/); no local dir expected
    const reservedSkillRoots = new Set(['learned', 'imported']);
    const skillRefs = contentNoCodeBlocks.matchAll(/skills\/([a-z][-a-z0-9]*)\//g);
    for (const match of skillRefs) {
      const refName = match[1];
      if (reservedSkillRoots.has(refName) || validSkills.has(refName)) continue;
      console.warn(`WARN: ${file} - references skill directory skills/${refName}/ (not found locally)`);
      warnCount++;
    }

    // Check agent name references in workflow diagrams (e.g., "planner -> tdd-guide")
    const workflowLines = contentNoCodeBlocks.matchAll(/^([a-z][-a-z0-9]*(?:\s*->\s*[a-z][-a-z0-9]*)+)$/gm);
    for (const match of workflowLines) {
      const agents = match[1].split(/\s*->\s*/);
      for (const agent of agents) {
        if (!validAgents.has(agent)) {
          console.error(`ERROR: ${file} - workflow references non-existent agent "${agent}"`);
          hasErrors = true;
        }
      }
    }
  }

  if (hasErrors) {
    process.exit(1);

View on GitHub (pinned to 8321021c54)