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

  1. Check permissions on skillDir and its parent with ls -la and fix with chmod/chown
  2. Run the command as a user with write access, or with sudo if appropriate
  3. Point the skill output to a writable directory via the relevant CLI/config option
  4. 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

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


AI-assisted analysis of yamadashy/repomix@f465ad9093 (2026-08-29). Data as JSON: /api/errors/548e1998aa09fec0. Report an issue: GitHub.