{"record":{"id":"548e1998aa09fec0","repo":"yamadashy/repomix","slug":"failed-to-write-skill-output-to-skilldir-permi","errorCode":null,"errorMessage":"Failed to write skill output to ${skillDir}: Permission denied. Please check directory permissions.","messagePattern":"Failed to write skill output to (.+?): Permission denied\\. Please check directory permissions\\.","errorType":"exception","errorClass":"RepomixError","httpStatus":null,"severity":"error","filePath":"src/core/skill/writeSkillOutput.ts","lineNumber":49,"sourceCode":"    // Write SKILL.md\n    const skillMdPath = path.join(skillDir, 'SKILL.md');\n    await deps.writeFile(skillMdPath, output.skillMd, 'utf-8');\n\n    // Write reference files\n    await deps.writeFile(path.join(referencesDir, 'summary.md'), output.references.summary, 'utf-8');\n    await deps.writeFile(path.join(referencesDir, 'project-structure.md'), output.references.structure, 'utf-8');\n    await deps.writeFile(path.join(referencesDir, 'files.md'), output.references.files, 'utf-8');\n\n    // Write tech-stacks.md if available\n    if (output.references.techStack) {\n      await deps.writeFile(path.join(referencesDir, 'tech-stacks.md'), output.references.techStack, 'utf-8');\n    }\n\n    return skillDir;\n  } catch (error) {\n    const nodeError = error as NodeJS.ErrnoException;\n    if (nodeError.code === 'EPERM' || nodeError.code === 'EACCES') {\n      throw new RepomixError(\n        `Failed to write skill output to ${skillDir}: Permission denied. Please check directory permissions.`,\n        { cause: error instanceof Error ? error : undefined },\n      );\n    }\n    throw new RepomixError(`Failed to write skill output: ${error instanceof Error ? error.message : String(error)}`, {\n      cause: error instanceof Error ? error : undefined,\n    });\n  }\n};\n","sourceCodeStart":31,"sourceCodeEnd":59,"githubUrl":"https://github.com/yamadashy/repomix/blob/f465ad909315a22120636baf03fa5e28701a50cb/src/core/skill/writeSkillOutput.ts#L31-L59","documentation":"writeSkillOutput wraps filesystem errors when creating/writing the skill output directory. When the underlying Node error has code EPERM or EACCES, it rethrows a RepomixError stating permission was denied on skillDir, attaching the original error as cause. It exists to convert cryptic fs errors into an actionable message.","triggerScenarios":"Calling writeSkillOutput when fs.mkdir or fs.writeFile on skillDir fails with EPERM/EACCES — e.g. the parent directory is read-only, owned by another user, or an existing skillDir is not writable.","commonSituations":"Running repomix under a different user than the owner of ~/.claude/skills or similar target dir; CI containers writing to a root-owned path; SELinux/AppArmor denial; disk mounted read-only.","solutions":["Check permissions on skillDir and its parent with ls -la and fix with chmod/chown","Run the command as a user with write access, or with sudo if appropriate","Point the skill output to a writable directory via the relevant CLI/config option","Check for read-only mounts or security modules (SELinux/AppArmor) denying the write"],"exampleFix":"// before\nawait writeSkillOutput('/root/.claude/skills/repomix', ...);\n// after\nawait writeSkillOutput(path.join(os.homedir(), '.claude/skills/repomix'), ...);","handlingStrategy":"try-catch","validationCode":"import { access, constants } from 'node:fs/promises';\nawait access(skillDir, constants.W_OK); // or access(path.dirname(skillDir), constants.W_OK)","typeGuard":"const isPermissionError = (e: unknown): e is NodeJS.ErrnoException =>\n  typeof e === 'object' && e !== null && 'code' in e && ((e as NodeJS.ErrnoException).code === 'EPERM' || (e as NodeJS.ErrnoException).code === 'EACCES');","tryCatchPattern":"try {\n  await writeSkillOutput(skillDir, output);\n} catch (err) {\n  if (err instanceof RepomixError && err.message.includes('Permission denied')) {\n    console.error(`No write permission for ${skillDir}; pick another directory or fix ownership.`);\n  } else throw err;\n}","preventionTips":["Check writability of the target dir (fs access W_OK) before invoking","Prefer writing under os.homedir() or the project dir over system paths","Avoid running under sudo, which creates root-owned artifacts","On CI, grant the runner user ownership of the output directory"],"tags":["filesystem","permissions","skill-output"],"backgroundTag":"permission-denied-eacces","analyzedSha":"f465ad909315a22120636baf03fa5e28701a50cb","analyzedAt":"2026-08-29T01:27:42.024Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}