{"record":{"id":"d50cb2a043bc36cc","repo":"gitbutlerapp/gitbutler","slug":"installation-path-is-a-file-not-a-directory-p","errorCode":null,"errorMessage":"Installation path {} is a file, not a directory. Please specify a directory path.","messagePattern":"Installation path (.+?) is a file, not a directory\\. Please specify a directory path\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/skill/mod.rs","lineNumber":1305,"sourceCode":"    } else {\n        None\n    };\n    let installed_for_driving_agent = agent_default_path.is_some();\n    let install_paths = if let Some(custom) = custom_path {\n        vec![resolve_custom_path(&custom, ctx, global)?]\n    } else if detect {\n        detect_install_paths(ctx, global)?\n    } else if let Some(path) = agent_default_path {\n        vec![path]\n    } else {\n        vec![prompt_for_install_path(ctx, global, out, &mut progress)?]\n    };\n\n    let mut version = \"\";\n    for install_path in &install_paths {\n        // Validate installation path\n        if install_path.exists() && install_path.is_file() {\n            anyhow::bail!(\n                \"Installation path {} is a file, not a directory. Please specify a directory path.\",\n                install_path.display()\n            );\n        }\n\n        // Check if files already exist and warn user\n        if install_path.join(\"SKILL.md\").exists()\n            && let Some(writer) = out.for_human()\n        {\n            writeln!(writer)?;\n            writeln!(\n                writer,\n                \"{} Skill files already exist at {}\",\n                t.sym().warning,\n                t.config_value.paint(install_path.display().to_string())\n            )?;\n            writeln!(writer, \"  Overwriting existing files...\")?;\n            writeln!(writer)?;","sourceCodeStart":1287,"sourceCodeEnd":1323,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/command/skill/mod.rs#L1287-L1323","documentation":"Before installing, `install_skill` validates each resolved installation path. If a path exists on disk but is a regular file rather than a directory, writing skill files into it is impossible, so it bails with a message naming the offending path.","triggerScenarios":"Running `but skill install --path <file>` (or `--detect` resolving to a path) where the target exists and `is_file()` is true, e.g. pointing at `~/.claude/skills/gitbutler.md` or a symlink to a file.","commonSituations":"Typos in the path pointing at a file; previously created a file at that location; agent configs where the skills entry is a file, not a directory.","solutions":["Remove or rename the file at the target path and re-run.","Pass `--path <dir>` pointing to a directory (create it first with mkdir -p if needed).","Check the resolved path (it's printed in the error) and correct it."],"exampleFix":"// before\nbut skill install --path ~/.claude/skills/gitbutler.md\n// error: Installation path ... is a file, not a directory.\n\n// after\nmkdir -p ~/.claude/skills/gitbutler && but skill install --path ~/.claude/skills/gitbutler","handlingStrategy":"validation","validationCode":"# shell\n[ -f \"$SKILL_PATH\" ] && { echo \"$SKILL_PATH is a file\"; exit 1; }\nmkdir -p \"$SKILL_PATH\"","typeGuard":null,"tryCatchPattern":"if [ -f \"$SKILL_PATH\" ]; then rm -i \"$SKILL_PATH\"; fi\nbut skill install --path \"$SKILL_PATH\"","preventionTips":["mkdir -p the target directory before installing.","Check that the target isn't a file (`[ -f path ]`).","Avoid symlinks to files at the install path."],"tags":["cli","filesystem","path-validation"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}