{"record":{"id":"14f68bf48be51811","repo":"affaan-m/ECC","slug":"warn-file-references-skill-directory-skills-refname-not","errorCode":null,"errorMessage":"WARN: ${file} - references skill directory skills/${refName}/ (not found locally)","messagePattern":"WARN: (.+?) - references skill directory skills/(.+?)/ \\(not found locally\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"scripts/ci/validate-commands.js","lineNumber":160,"sourceCode":"\n    // Check agent references (e.g., \"agents/planner.md\" or \"`planner` agent\")\n    const agentPathRefs = contentNoCodeBlocks.matchAll(/agents\\/([a-z][-a-z0-9]*)\\.md/g);\n    for (const match of agentPathRefs) {\n      const refName = match[1];\n      if (!validAgents.has(refName)) {\n        console.error(`ERROR: ${file} - references non-existent agent agents/${refName}.md`);\n        hasErrors = true;\n      }\n    }\n\n    // Check skill directory references (e.g., \"skills/tdd-workflow/\")\n    // learned and imported are reserved roots (~/.claude/skills/); no local dir expected\n    const reservedSkillRoots = new Set(['learned', 'imported']);\n    const skillRefs = contentNoCodeBlocks.matchAll(/skills\\/([a-z][-a-z0-9]*)\\//g);\n    for (const match of skillRefs) {\n      const refName = match[1];\n      if (reservedSkillRoots.has(refName) || validSkills.has(refName)) continue;\n      console.warn(`WARN: ${file} - references skill directory skills/${refName}/ (not found locally)`);\n      warnCount++;\n    }\n\n    // Check agent name references in workflow diagrams (e.g., \"planner -> tdd-guide\")\n    const workflowLines = contentNoCodeBlocks.matchAll(/^([a-z][-a-z0-9]*(?:\\s*->\\s*[a-z][-a-z0-9]*)+)$/gm);\n    for (const match of workflowLines) {\n      const agents = match[1].split(/\\s*->\\s*/);\n      for (const agent of agents) {\n        if (!validAgents.has(agent)) {\n          console.error(`ERROR: ${file} - workflow references non-existent agent \"${agent}\"`);\n          hasErrors = true;\n        }\n      }\n    }\n  }\n\n  if (hasErrors) {\n    process.exit(1);","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/ci/validate-commands.js#L142-L178","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the reference in the flagged file to point at an existing skill directory","If the skill was renamed, update all occurrences of the old name to the new directory name","If the skill should exist, add skills/<refName>/SKILL.md and register it per CONTRIBUTING.md","If the reference is intentionally illustrative, move it inside a code block so the validator's contentNoCodeBlocks filter excludes it"],"exampleFix":"// before (docs/command.md)\nRun the workflow described in skills/review-workflow/...\n// after\nRun the workflow described in skills/code-review/...","handlingStrategy":"validation","validationCode":"const refName = 'code-review';\nconst valid = fs.existsSync(path.join('skills', refName, 'SKILL.md'));\nif (!valid) console.warn(`skills/${refName}/ not found`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run node scripts/ci/validate-commands.js locally before pushing","Use find/replace across the repo when renaming a skill directory","Put illustrative skill paths inside code blocks","Only reference skills registered in skills/ and the catalog"],"tags":["ci","documentation","broken-reference","skills"],"backgroundTag":"resource-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}