{"record":{"id":"8a7c90e7aebc173f","repo":"microsoft/playwright","slug":"skill-source-directory-not-found-sourcedir","errorCode":null,"errorMessage":"Skill source directory not found: ${sourceDir}","messagePattern":"Skill source directory not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/utils/installSkills.ts","lineNumber":36,"sourceCode":"\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { libPath } from '../../package';\n\nexport const allSkills = ['playwright-cli', 'playwright-component-testing', 'playwright-trace'] as const;\n\nexport type SkillName = typeof allSkills[number];\nexport type SkillTarget = 'claude' | 'agents';\n\nexport async function installSkills(skills: readonly SkillName[], target: SkillTarget = 'claude', options?: { global?: boolean }) {\n  const cwd = process.cwd();\n  const baseDir = options?.global ? os.homedir() : cwd;\n  for (const skill of skills) {\n    const sourceDir = libPath('tools', 'skills', skill);\n    if (!fs.existsSync(sourceDir))\n      throw new Error(`Skill source directory not found: ${sourceDir}`);\n    const destDir = path.join(baseDir, `.${target}`, 'skills', skill);\n    await fs.promises.cp(sourceDir, destDir, { recursive: true });\n    console.log(`✅ Skill installed to \\`${options?.global ? destDir : path.relative(cwd, destDir)}\\`.`);\n  }\n}\n","sourceCodeStart":18,"sourceCodeEnd":42,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/tools/utils/installSkills.ts#L18-L42","documentation":"Thrown by installSkills() when the skill source directory computed by libPath('tools','skills',<name>) does not exist. libPath resolves inside the installed playwright-core package, so the error means the requested skill's assets were not shipped/present in the package layout. allSkills enumerates the supported names ('playwright-cli','playwright-component-testing','playwright-trace').","triggerScenarios":"Running `npx playwright install-skills <name>` with a name not in allSkills, or against an installation where the tools/skills/<name> directory is missing (corrupted/partial install, dev build without bundling, wrong package).","commonSituations":"Using a dev/git checkout where skill assets are not generated/copied; partial npm install; typo in skill name; version that does not yet ship the requested skill.","solutions":["Use one of the supported skill names: playwright-cli, playwright-component-testing, or playwright-trace.","Reinstall the Playwright package cleanly (rm -rf node_modules and npm install) to restore missing bundled assets.","If running from a git checkout, run the build/watch so that skill assets are placed under tools/skills/.","Upgrade Playwright to a version that ships the skill you requested."],"exampleFix":"// before\nnpx playwright install-skills playwright-snapshot\n// after\nnpx playwright install-skills playwright-trace","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nimport { allSkills } from '../tools/utils/installSkills';\nfunction assertSkillAvailable(name: string) {\n  if (!(allSkills as readonly string[]).includes(name))\n    throw new Error(`Unknown skill: ${name}. Valid: ${allSkills.join(', ')}`);\n  if (!fs.existsSync(libPath('tools', 'skills', name)))\n    throw new Error(`Skill not shipped in this install: ${name}`);\n}","typeGuard":"function isSkillName(name: string): name is typeof allSkills[number] {\n  return (allSkills as readonly string[]).includes(name);\n}","tryCatchPattern":null,"preventionTips":["Restrict skill names to the allSkills constant (playwright-cli, playwright-component-testing, playwright-trace).","Reinstall Playwright cleanly if bundled assets are missing.","Run the build in git checkouts so skill assets are generated before install-skills."],"tags":["skills","setup","package","filesystem","validation"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}