{"record":{"id":"37f44a1de8f06bb2","repo":"affaan-m/ECC","slug":"skill-file-not-found-skillfilepath","errorCode":null,"errorMessage":"Skill file not found: ${skillFilePath}","messagePattern":"Skill file not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/versioning.js","lineNumber":36,"sourceCode":"    throw new Error('skillPath is required');\n  }\n\n  const resolvedPath = path.resolve(skillPath);\n  if (path.basename(resolvedPath) === 'SKILL.md') {\n    return path.dirname(resolvedPath);\n  }\n\n  return resolvedPath;\n}\n\nfunction getSkillFilePath(skillPath) {\n  return path.join(normalizeSkillDir(skillPath), 'SKILL.md');\n}\n\nfunction ensureSkillExists(skillPath) {\n  const skillFilePath = getSkillFilePath(skillPath);\n  if (!fs.existsSync(skillFilePath)) {\n    throw new Error(`Skill file not found: ${skillFilePath}`);\n  }\n\n  return skillFilePath;\n}\n\nfunction getVersionsDir(skillPath) {\n  return path.join(normalizeSkillDir(skillPath), VERSION_DIRECTORY_NAME);\n}\n\nfunction getEvolutionDir(skillPath) {\n  return path.join(normalizeSkillDir(skillPath), EVOLUTION_DIRECTORY_NAME);\n}\n\nfunction getEvolutionLogPath(skillPath, logType) {\n  if (!EVOLUTION_LOG_TYPES.includes(logType)) {\n    throw new Error(`Unknown evolution log type: ${logType}`);\n  }\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/skill-evolution/versioning.js#L18-L54","documentation":"Thrown by ensureSkillExists() in the skill-evolution versioning module when the resolved skill directory does not contain a SKILL.md file. The library refuses to version, snapshot, or roll back a skill it cannot locate, because every other operation reads and writes that file. The thrown message embeds the absolute resolved path so the caller can see exactly where the lookup failed.","triggerScenarios":"Calling createVersion(skillPath), rollbackTo(skillPath, ...), ensureSkillVersioning(skillPath), or appendEvolutionRecord(...) with a skillPath that points at a directory missing SKILL.md; passing a path to a file other than SKILL.md whose sibling directory has no SKILL.md; passing a relative path that resolves outside the skills tree; calling versioning APIs before the skill was scaffolded.","commonSituations":"Typo in the skill directory name; running versioning tooling against a partially-generated skill that has frontmatter only; renaming a skill folder without moving SKILL.md; pointing tooling at the parent skills/ directory instead of the individual skill folder; CI running against a shallow checkout that excluded the skill files.","solutions":["Verify the resolved path printed in the message actually contains a SKILL.md file: ls -la <printedPath>.","Pass the skill directory (the folder containing SKILL.md), or the SKILL.md path itself — normalizeSkillDir accepts both forms.","If the skill was never created, scaffold it first (create the directory and a SKILL.md with frontmatter) before invoking any versioning API.","Check for path typos, wrong working directory (paths are resolved with path.resolve, so relative paths depend on process.cwd()), or case-sensitivity mismatches on case-sensitive filesystems."],"exampleFix":"// before\ncreateVersion('skills/tdd-worflow');  // typo -> Skill file not found\n\n// after\ncreateVersion('skills/tdd-workflow');  // directory that contains SKILL.md","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst path = require('path');\n\nfunction resolveSkillFile(skillPath) {\n  const dir = path.basename(skillPath) === 'SKILL.md' ? path.dirname(skillPath) : skillPath;\n  const skillFile = path.join(path.resolve(dir), 'SKILL.md');\n  return fs.existsSync(skillFile) ? skillFile : null;\n}\n\n// before calling createVersion / rollbackTo / ensureSkillVersioning\nconst skillFile = resolveSkillFile(skillPath);\nif (!skillFile) {\n  throw new Error(`Refusing to call versioning API: no SKILL.md at ${skillPath}`);\n}","typeGuard":"function isSkillDirectory(target) {\n  if (typeof target !== 'string' || target.trim().length === 0) return false;\n  try {\n    const dir = path.basename(target) === 'SKILL.md' ? path.dirname(target) : target;\n    return fs.existsSync(path.join(path.resolve(dir), 'SKILL.md'));\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  createVersion(skillPath);\n} catch (error) {\n  if (/Skill file not found/.test(error.message)) {\n    // scaffold the skill or fix the path, then retry or skip\n    return;\n  }\n  throw error;\n}","preventionTips":["Always pass the skill folder (the directory that contains SKILL.md) — both forms are accepted but the folder is unambiguous.","Validate paths at your API boundary with resolveSkillFile before invoking any versioning API.","Treat a missing SKILL.md as a programmer error, not a runtime condition — fail early at ingress.","In tests, create the skill directory and SKILL.md in a beforeEach rather than assuming the fixture exists."],"tags":["skill-evolution","filesystem","validation","path-resolution"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}