yamadashy/repomix · error · RepomixError

Failed to write skill output to

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.

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.

Appendix: 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)