{"record":{"id":"9d04f12cf72cc7ea","repo":"Fission-AI/OpenSpec","slug":"refusing-to-generate-join-outdir-entry-name","errorCode":null,"errorMessage":"Refusing to generate: ${join(outDir, entry.name)} is a symlink. Remove it and re-run.","messagePattern":"Refusing to generate: (.+?) is a symlink\\. Remove it and re-run\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/skillssh-shared.mjs","lineNumber":33,"sourceCode":" * standalone distribution it would just churn the files on every release.\n */\nexport function stripVolatileFrontmatter(content) {\n  return content.replace(/^ {2}generatedBy: .*\\n/m, '');\n}\n\n/**\n * Remove existing skill subdirectories (clears any renamed/removed skills)\n * while preserving top-level files like README.md. Refuses to run if the tree\n * contains a symlink: deleting one would only unlink it, and a symlinked skill\n * directory would otherwise let later writes land outside the repo.\n */\nexport function cleanSkillSubdirectories(outDir) {\n  mkdirSync(outDir, { recursive: true });\n  const entries = readdirSync(outDir, { withFileTypes: true });\n  // Reject before deleting anything so a bad tree is left fully intact.\n  for (const entry of entries) {\n    if (entry.isSymbolicLink()) {\n      throw new Error(\n        `Refusing to generate: ${join(outDir, entry.name)} is a symlink. Remove it and re-run.`\n      );\n    }\n  }\n  for (const entry of entries) {\n    if (entry.isDirectory()) {\n      rmSync(join(outDir, entry.name), { recursive: true, force: true });\n    }\n  }\n}\n\n/**\n * Create `<outDir>/<dirName>` and return its path, guaranteeing the write\n * target is a real directory contained in outDir — never a path-traversing\n * name and never a symlink that would redirect the write elsewhere.\n */\nexport function prepareSkillDirectory(outDir, dirName) {\n  if (!/^[a-z0-9][a-z0-9-]*$/.test(dirName)) {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/scripts/skillssh-shared.mjs#L15-L51","documentation":"Error \"Refusing to generate: ${join(outDir, entry.name)} is a symlink. Remove it and re-run.\" thrown in Fission-AI/OpenSpec.","triggerScenarios":"Thrown at scripts/skillssh-shared.mjs:33 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6926ccb18afa4ff621112813e9968334576ee11a","analyzedAt":"2026-08-25T12:29:45.729Z","schemaVersion":2},"datasetVersion":"2026-08-25T16:17:27.014Z"}