gitbutlerapp/gitbutler · error
Installation path {} is a file, not a directory. Please spec
Error message
Installation path {} is a file, not a directory. Please specify a directory path. What it means
Before writing skill files into a destination, `but skill install` validates that the path can hold a directory tree. If install_path exists and is a regular file (is_file()), creating SKILL.md and references/ under it is impossible, so the command fails with the offending path instead of attempting partial writes.
Source
Thrown at crates/but/src/command/skill/mod.rs:1115
} else {
None
};
let installed_for_driving_agent = agent_default_path.is_some();
let install_paths = if let Some(custom) = custom_path {
vec![resolve_custom_path(&custom, ctx, global)?]
} else if detect {
detect_install_paths(ctx, global)?
} else if let Some(path) = agent_default_path {
vec![path]
} else {
vec![prompt_for_install_path(ctx, global, out, &mut progress)?]
};
let mut version = "";
for install_path in &install_paths {
// Validate installation path
if install_path.exists() && install_path.is_file() {
anyhow::bail!(
"Installation path {} is a file, not a directory. Please specify a directory path.",
install_path.display()
);
}
// Check if files already exist and warn user
if install_path.join("SKILL.md").exists()
&& let Some(writer) = out.for_human()
{
writeln!(writer)?;
writeln!(
writer,
"{} Skill files already exist at {}",
t.sym().warning,
t.config_value.paint(install_path.display().to_string())
)?;
writeln!(writer, " Overwriting existing files...")?;
writeln!(writer)?;View on GitHub (pinned to caf1f223d3)
Solutions
- Point --path at a directory path that is free or already a directory
- Move or delete the conflicting file: `mv ~/.claude/skills ~/.claude/skills.bak`
- If the path is a symlink, retarget it to a directory
Example fix
$ ls -l ~/.claude/skills # regular file -> fails $ rm ~/.claude/skills $ but skill install --path ~/.claude/skills
Defensive patterns
Strategy: validation
Validate before calling
match std::fs::metadata(&path) {
Ok(m) if m.is_file() => { /* pick another path or stop before invoking */ }
Ok(m) if m.is_dir() => { /* safe */ }
_ => { /* path free: also safe */ }
} Prevention
- Check fs::metadata on the target before installing
- Follow symlinks when validating (metadata does; symlink_metadata does not)
- In dotfiles repos, ensure skill directories are not shadowed by files
When it happens
Trigger: Passing --path that resolves to an existing regular file - a leftover marker file named like the target directory, or a symlink pointing at a file rather than a directory.
Common situations: Dotfile layouts where ~/.claude/skills is a file, leftovers from earlier tooling, typos in --path colliding with an existing file name.
Related errors
- Cannot use relative --path outside a git repository unless -
- Could not detect an existing GitButler skill installation. R
- No supported agent was detected. In non-interactive mode, sp
- Human input required - run this in a terminal, or specify --
- Cannot use both --detect and --path options together
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/d50cb2a043bc36cc.
Report an issue: GitHub.