{"record":{"id":"64e9ab67f3127207","repo":"Fission-AI/OpenSpec","slug":"refusing-to-write-through-skilldir-not-a-real","errorCode":null,"errorMessage":"Refusing to write through ${skillDir}: not a real directory.","messagePattern":"Refusing to write through (.+?): not a real directory\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/skillssh-shared.mjs","lineNumber":57,"sourceCode":"    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)) {\n    throw new Error(`Refusing to generate: unsafe skill directory name ${JSON.stringify(dirName)}`);\n  }\n  const skillDir = join(outDir, dirName);\n  mkdirSync(skillDir, { recursive: true });\n  if (!lstatSync(skillDir).isDirectory()) {\n    throw new Error(`Refusing to write through ${skillDir}: not a real directory.`);\n  }\n  return skillDir;\n}\n","sourceCodeStart":39,"sourceCodeEnd":61,"githubUrl":"https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/scripts/skillssh-shared.mjs#L39-L61","documentation":"Error \"Refusing to write through ${skillDir}: not a real directory.\" thrown in Fission-AI/OpenSpec.","triggerScenarios":"Thrown at scripts/skillssh-shared.mjs:57 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"}