yamadashy/repomix · error · RepomixError

Failed to write skill output: ${error instanceof Error ? err

Error message

Failed to write skill output: ${error instanceof Error ? error.message : String(error)}

What it means

This is the catch-all wrapper in writeSkillOutput: any filesystem failure that is NOT EPERM/EACCES is rethrown as a RepomixError with 'Failed to write skill output: <message>'. It preserves the original error as cause so callers can inspect the root cause.

Source

Thrown at src/core/skill/writeSkillOutput.ts:54

    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. Read error.cause (or the appended message) to identify the underlying errno code
  2. Free disk space if the cause is ENOSPC
  3. Remove any file occupying the skillDir path so the directory can be created
  4. Close fd leaks / raise ulimit if the cause is EMFILE
  5. Retry the command after fixing the environment

Example fix

// before (skillDir occupied by a regular file)
$ ls ~/.claude/skills/repomix   # -> a file
// after
$ rm ~/.claude/skills/repomix && repomix --skill
Defensive patterns

Strategy: try-catch

Validate before calling

import { stat } from 'node:fs/promises';
const s = await stat(path.dirname(skillDir)).catch(() => null);
if (!s?.isDirectory()) throw new Error(`parent of skillDir missing: ${skillDir}`);
if (await stat(skillDir).then(s2 => !s2.isDirectory(), () => false)) throw new Error('skillDir exists as a file');

Type guard

const hasCause = (e: unknown): e is { cause: unknown } =>
  typeof e === 'object' && e !== null && 'cause' in e;

Try / catch

try {
  await writeSkillOutput(skillDir, output);
} catch (err) {
  const cause = (err as { cause?: Error })?.cause;
  console.error(`skill write failed: ${cause?.message ?? err.message}`); // route on ENOSPC/ENOENT etc.
}

Prevention

When it happens

Trigger: Any fs error other than EPERM/EACCES while creating or writing skillDir — ENOSPC (disk full), ENOENT (parent path vanished), EISDIR, EMFILE/ENFILE (fd exhaustion), EROFS, or a non-Error throw.

Common situations: Disk quota exceeded on CI; antivirus/file-lock interference on Windows; target path exists as a file not a directory; too many open files.

Related errors


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