yamadashy/repomix · error · RepomixError
Failed to write skill output to ${skillDir}: Permission deni
Error message
Failed to write skill output to ${skillDir}: Permission denied. Please check directory permissions. What it means
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.
Source
Thrown at src/core/skill/writeSkillOutput.ts:49
// Write SKILL.md
const skillMdPath = path.join(skillDir, 'SKILL.md');
await deps.writeFile(skillMdPath, output.skillMd, 'utf-8');
// Write reference files
await deps.writeFile(path.join(referencesDir, 'summary.md'), output.references.summary, 'utf-8');
await deps.writeFile(path.join(referencesDir, 'project-structure.md'), output.references.structure, 'utf-8');
await deps.writeFile(path.join(referencesDir, 'files.md'), output.references.files, 'utf-8');
// Write tech-stacks.md if available
if (output.references.techStack) {
await deps.writeFile(path.join(referencesDir, 'tech-stacks.md'), output.references.techStack, 'utf-8');
}
return skillDir;
} catch (error) {
const nodeError = error as NodeJS.ErrnoException;
if (nodeError.code === 'EPERM' || nodeError.code === 'EACCES') {
throw new RepomixError(
`Failed to write skill output to ${skillDir}: Permission denied. Please check directory permissions.`,
{ cause: error instanceof Error ? error : undefined },
);
}
throw new RepomixError(`Failed to write skill output: ${error instanceof Error ? error.message : String(error)}`, {
cause: error instanceof Error ? error : undefined,
});
}
};
View on GitHub (pinned to f465ad9093)
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
Example fix
// before
await writeSkillOutput('/root/.claude/skills/repomix', ...);
// after
await writeSkillOutput(path.join(os.homedir(), '.claude/skills/repomix'), ...); Defensive patterns
Strategy: try-catch
Validate before calling
import { access, constants } from 'node:fs/promises';
await access(skillDir, constants.W_OK); // or access(path.dirname(skillDir), constants.W_OK) Type guard
const isPermissionError = (e: unknown): e is NodeJS.ErrnoException => typeof e === 'object' && e !== null && 'code' in e && ((e as NodeJS.ErrnoException).code === 'EPERM' || (e as NodeJS.ErrnoException).code === 'EACCES');
Try / catch
try {
await writeSkillOutput(skillDir, output);
} catch (err) {
if (err instanceof RepomixError && err.message.includes('Permission denied')) {
console.error(`No write permission for ${skillDir}; pick another directory or fix ownership.`);
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to copy output file to ${targetPath}: Permission deni
- Could not read the remote repository's config (${configName}
- Permission denied while scanning directory. Please check fol
- Failed to write skill output: ${error instanceof Error ? err
- Failed to read file: ${filePath}
AI-assisted analysis of yamadashy/repomix@f465ad9093 (2026-08-29).
Data as JSON: /api/errors/548e1998aa09fec0.
Report an issue: GitHub.