yamadashy/repomix · error · RepomixError
Skill output path exists but is not a directory: ${skillDir}
Error message
Skill output path exists but is not a directory: ${skillDir} What it means
In non-interactive skill generation, prepareSkillDir checks the target skill directory with access() then stat(). If the path exists but stat reports it is not a directory (a regular file, symlink to a file, FIFO, etc.), Repomix throws this RepomixError rather than deleting or clobbering a non-directory path. resolveAndPrepareSkillDir calls this with the resolved skill output path before writing the skill.
Source
Thrown at src/cli/prompts/skillPrompts.ts:124
/**
* Prepare skill directory for non-interactive mode.
* Handles force overwrite by removing existing directory.
*/
export const prepareSkillDir = async (
skillDir: string,
force: boolean,
deps = {
access: fs.access,
rm: fs.rm,
stat: fs.stat,
},
): Promise<void> => {
try {
await deps.access(skillDir);
// Path exists - check if it's a directory
const stats = await deps.stat(skillDir);
if (!stats.isDirectory()) {
throw new RepomixError(`Skill output path exists but is not a directory: ${skillDir}`);
}
// Directory exists
if (force) {
await deps.rm(skillDir, { recursive: true, force: true });
} else {
throw new RepomixError(`Skill directory already exists: ${skillDir}. Use --force to overwrite.`);
}
} catch (error) {
// Re-throw if it's not a "file not found" error
if ((error as NodeJS.ErrnoException)?.code !== 'ENOENT') {
throw error;
}
// Directory doesn't exist - good to go
}
};
/**
* Resolve skill output path and prepare directory for non-interactive mode.View on GitHub (pinned to f465ad9093)
Solutions
- Inspect the path: `ls -la <skillDir>` / `file <skillDir>` to see what occupies it.
- Remove or rename the offending file: `rm <skillDir>` (or mv it aside), then re-run the command.
- Fix your output argument to point at a fresh directory path that does not collide with an existing file.
- If the entry is a stale artifact of a prior run, deleting it is safe; the command will then create the directory.
Example fix
# before repomix --skill --output my-skill # my-skill is a regular file # after rm my-skill # or: mv my-skill my-skill.bak repomix --skill --output my-skill
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs/promises';
try {
const st = await fs.stat(skillDir);
if (!st.isDirectory()) {
console.error(`${skillDir} exists and is not a directory; remove or rename it first.`);
process.exit(1);
}
} catch { /* does not exist: fine */ } Try / catch
try {
await resolveAndPrepareSkillDir(skillOutput, cwd, force);
} catch (e) {
if (e instanceof RepomixError && e.message.includes('exists but is not a directory')) {
console.error('Target path is a file; delete/rename it or pick another output path.');
} else throw e;
} Prevention
- Check the output path with `ls -la` before running non-interactively.
- Don't pass output paths that collide with existing files.
- Use distinct names per skill generation to avoid collisions.
- Watch for stale files left by previous failed runs at the same path.
When it happens
Trigger: Running skill generation non-interactively (with an explicit output path) where skillDir already exists as a non-directory — commonly a plain file was created earlier at the same path, or a symlink to a file occupies the path.
Common situations: A previous failed run left a file named like the skill directory; the user's output value collides with an existing file (e.g. `--output my-skill` where my-skill is a file); editors/tools created a lockfile or notes file at that name.
Related errors
- Skill directory already exists: ${skillDir}. Use --force to
- Skill generation cancelled
- Config file not found at ${argConfigPath}
- --skill-output can only be used with --skill-generate
- --force can only be used with --skill-generate
AI-assisted analysis of yamadashy/repomix@f465ad9093 (2026-08-29).
Data as JSON: /api/errors/c825ffb562e5965d.
Report an issue: GitHub.