{"record":{"id":"ab988770e7b61d99","repo":"affaan-m/ECC","slug":"skillpath-is-required-ab9887","errorCode":null,"errorMessage":"skillPath is required","messagePattern":"skillPath is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/versioning.js","lineNumber":18,"sourceCode":"'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst { appendFile, ensureDir } = require('../utils');\n\nconst VERSION_DIRECTORY_NAME = '.versions';\nconst EVOLUTION_DIRECTORY_NAME = '.evolution';\nconst EVOLUTION_LOG_TYPES = Object.freeze([\n  'observations',\n  'inspections',\n  'amendments',\n]);\n\nfunction normalizeSkillDir(skillPath) {\n  if (!skillPath || typeof skillPath !== 'string') {\n    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}`);","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/skill-evolution/versioning.js#L1-L36","documentation":"normalizeSkillDir in scripts/lib/skill-evolution/versioning.js throws 'skillPath is required' when the skillPath argument is falsy or not a string. It is the entry validation for path resolution helpers (getSkillFilePath, getVersionsDir, getEvolutionDir), which cannot compute any paths without a base skill directory. It also accepts a direct path to a SKILL.md file and resolves it to its parent directory.","triggerScenarios":"Calling getSkillFilePath/getVersionsDir/getEvolutionDir with skillPath undefined, null, an empty string, or a non-string (number, object). Also occurs when an upstream lookup for the skill directory returned nothing and the null result was forwarded.","commonSituations":"Calling the helpers before a skill is installed/located on disk; a failed skill-name-to-path resolution earlier in the pipeline returning null; CLI scripts where the --skill-path flag was not provided; refactors that changed the helper signature and dropped the argument.","solutions":["Pass the skill directory path (or the SKILL.md file path) as a non-empty string to the helper.","If the path is discovered dynamically, resolve the skill directory first and fail early with a clear message when discovery returns nothing.","For CLI callers, validate that the --skill-path option is present and non-empty before invoking the versioning helpers."],"exampleFix":"// before\nconst versionsDir = versioning.getVersionsDir(opts.skillPath); // opts.skillPath may be undefined\n\n// after\nconst skillPath = opts.skillPath ?? path.join(process.cwd(), 'skills', opts.skillName);\nif (!skillPath || typeof skillPath !== 'string') {\n  throw new Error('--skill-path or --skill-name is required');\n}\nconst versionsDir = versioning.getVersionsDir(skillPath);","handlingStrategy":"type-guard","validationCode":"function assertSkillPath(skillPath) {\n  if (!skillPath || typeof skillPath !== 'string') {\n    throw new Error('skillPath is required: pass the skill directory or its SKILL.md path');\n  }\n}","typeGuard":"function hasSkillPath(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  const versionsDir = versioning.getVersionsDir(skillPath);\n} catch (err) {\n  if (err.message === 'skillPath is required') {\n    console.error('No skill path provided; resolve the skill directory (or pass its SKILL.md path) first.');\n    process.exitCode = 1;\n    return;\n  }\n  throw err;\n}","preventionTips":["Resolve the skill directory once at startup and assert it before calling any versioning helper.","Never forward possibly-null results of skill discovery directly into getSkillFilePath/getVersionsDir/getEvolutionDir.","In CLI scripts, validate that --skill-path (or an equivalent) is present before running path computations."],"tags":["validation","required-argument","paths","skill-evolution"],"backgroundTag":"missing-required-argument","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"}