{"record":{"id":"3ff2c93809494858","repo":"jackwener/OpenCLI","slug":"unknown-opencli-skill-name","errorCode":null,"errorMessage":"Unknown OpenCLI skill: ${name}","messagePattern":"Unknown OpenCLI skill: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"src/skills.ts","lineNumber":47,"sourceCode":"export function getSkillsRoot(packageRoot: string = findPackageRoot(MODULE_FILE)): string {\n  return path.join(packageRoot, 'skills');\n}\n\nexport function listOpenCliSkills(packageRoot?: string): OpenCliSkillInfo[] {\n  const skillsRoot = getSkillsRoot(packageRoot);\n  if (!fs.existsSync(skillsRoot)) return [];\n\n  return fs.readdirSync(skillsRoot, { withFileTypes: true })\n    .filter((entry) => entry.isDirectory() && entry.name.startsWith('opencli-'))\n    .map((entry) => readSkillInfo(skillsRoot, entry.name))\n    .filter((entry): entry is OpenCliSkillInfo => entry !== null)\n    .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function readOpenCliSkill(target: string, relpath = '', packageRoot?: string): OpenCliSkillReadResult {\n  const { name, pathInSkill } = parseSkillTarget(target, relpath);\n  if (!name.startsWith('opencli-')) {\n    throw new ArgumentError(`Unknown OpenCLI skill: ${name}`, 'Run \"opencli skills list\" to see available OpenCLI skills.');\n  }\n\n  const skillsRoot = getSkillsRoot(packageRoot);\n  const skillRoot = path.join(skillsRoot, name);\n  if (!isDirectory(skillRoot) || !fs.existsSync(path.join(skillRoot, 'SKILL.md'))) {\n    throw new ArgumentError(`Unknown OpenCLI skill: ${name}`, 'Run \"opencli skills list\" to see available OpenCLI skills.');\n  }\n\n  const relativePath = normalizeSkillPath(pathInSkill || 'SKILL.md');\n  const absolutePath = path.resolve(skillRoot, relativePath);\n  const relativeToRoot = path.relative(skillRoot, absolutePath);\n  if (relativeToRoot.startsWith('..') || path.isAbsolute(relativeToRoot)) {\n    throw new ArgumentError(`Invalid skill path: ${relativePath}`, 'Skill paths must stay inside the selected OpenCLI skill.');\n  }\n  if (!fs.existsSync(absolutePath) || !fs.statSync(absolutePath).isFile()) {\n    throw new ArgumentError(`Skill file not found: ${name}/${relativePath}`, 'Run \"opencli skills list <skill>\" is not supported yet; read SKILL.md or a known references/... file.');\n  }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/skills.ts#L29-L65","documentation":"readOpenCliSkill first parses the target into a skill name and requires it to start with the 'opencli-' prefix, since only built-in OpenCLI skills are resolvable through this API. A name without the prefix cannot be an OpenCLI skill, so it throws an ArgumentError immediately with a hint to run 'opencli skills list'.","triggerScenarios":"Calling readOpenCliSkill(target) where parseSkillTarget(target, relpath).name does not start with 'opencli-' — e.g. target \"git-fix\" or \"my-skill\" instead of \"opencli-git-fix\"; also passing a bare path with no name segment.","commonSituations":"Users passing a community/user skill name to the OpenCLI-specific reader; forgetting the 'opencli-' prefix in scripts or agent prompts; confusing readOpenCliSkill with the general skill reader.","solutions":["Prefix the skill name with 'opencli-' (e.g. \"opencli-commit\") and retry.","Run \"opencli skills list\" to see valid OpenCLI skill names and pick the exact one.","If the target is a user/community skill, use the general skill read API instead of readOpenCliSkill.","Validate the name in code before calling: name.startsWith('opencli-')."],"exampleFix":"// before\nreadOpenCliSkill(\"commit-helper\");\n// after\nreadOpenCliSkill(\"opencli-commit-helper\");","handlingStrategy":"validation","validationCode":"function isOpenCliTarget(target: string): boolean {\n  const { name } = parseSkillTarget(target, \"\");\n  return name.startsWith(\"opencli-\");\n}\nif (isOpenCliTarget(target)) readOpenCliSkill(target);","typeGuard":null,"tryCatchPattern":"import { ArgumentError } from \"./errors\";\ntry {\n  readOpenCliSkill(target);\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.startsWith(\"Unknown OpenCLI skill:\")) {\n    // fall back to the general skill reader or show `opencli skills list`\n  } else throw e;\n}","preventionTips":["Always use the 'opencli-' prefix for built-in skill targets.","Generate targets from 'opencli skills list' output instead of typing names.","Route user/community skills to the general skill API, not readOpenCliSkill.","Validate targets in agent/script code before invoking the reader."],"tags":["skills","validation","naming","argument"],"backgroundTag":"unknown-skill","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}