{"record":{"id":"d79d519bf456ad5a","repo":"paperclipai/paperclip","slug":"paperclip-skills-must-be-directories","errorCode":null,"errorMessage":"Paperclip skills must be directories.","messagePattern":"Paperclip skills must be directories\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/server-utils.ts","lineNumber":4272,"sourceCode":"\n  async function visit(candidate: string, relativePath: string): Promise<void> {\n    const stat = await fs.lstat(candidate);\n    if (stat.isSymbolicLink()) {\n      hash.update(`symlink:${relativePath}\\n`);\n      return;\n    }\n    if (stat.isDirectory()) {\n      hash.update(`dir:${relativePath}\\n`);\n      const entries = await fs.readdir(candidate, { withFileTypes: true });\n      entries.sort((left, right) => left.name.localeCompare(right.name));\n      for (const entry of entries) {\n        const childRelativePath = relativePath\n          ? `${relativePath}/${entry.name}`\n          : entry.name;\n        await visit(path.join(candidate, entry.name), childRelativePath);\n      }\n      return;\n    }\n    if (stat.isFile()) {\n      hash.update(`file:${relativePath}:${stat.mode}\\n`);\n      hash.update(await fs.readFile(candidate));\n      hash.update(\"\\n\");\n      return;\n    }\n    hash.update(`other:${relativePath}:${stat.mode}\\n`);\n  }\n\n  await visit(root, \"\");\n  return hash.digest(\"hex\");\n}\n\nasync function materializedSkillFingerprintMatches(\n  targetRoot: string,\n  sourceFingerprint: string,\n): Promise<boolean> {\n  try {","sourceCodeStart":4254,"sourceCodeEnd":4290,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/adapter-utils/src/server-utils.ts#L4254-L4290","documentation":"Error \"Paperclip skills must be directories.\" thrown in paperclipai/paperclip.","triggerScenarios":"Thrown at packages/adapter-utils/src/server-utils.ts:3164 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the skill path is a directory containing SKILL.md, not a file."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}