gitbutlerapp/gitbutler · error
Cannot use relative --path outside a git repository unless -
Error message
Cannot use relative --path outside a git repository unless --global is specified. Use --global --path <path> for a global installation, use an absolute path, or run from within a repository for local installation.
What it means
A relative --path for a local install is anchored at the discovered repository. Outside a git repository (ctx is None) with no --global, there is no anchor for a relative path, so install refuses it. Tilde paths are expanded before the check (expand_tilde), so `~/...` counts as absolute and is accepted.
Source
Thrown at crates/but/src/command/skill/mod.rs:1086
.all(|component| !component.contains('/') && !component.contains('\\'))
}),
"SkillFile path components must be non-empty and separator-free"
);
let mut progress = out.progress_channel();
// Validate flags
if detect && custom_path.is_some() {
anyhow::bail!("Cannot use both --detect and --path options together");
}
if ctx.is_none()
&& !global
&& let Some(custom) = custom_path.as_deref()
{
// Without a repository context, only absolute/tilde paths can be resolved without `--global`.
let expanded = expand_tilde(custom).unwrap_or_else(|| PathBuf::from(custom));
if !expanded.is_absolute() {
anyhow::bail!(
"Cannot use relative --path outside a git repository unless --global is specified.\n\
Use --global --path <path> for a global installation, use an absolute path, or run from within a repository for local installation."
);
}
}
// Determine installation path(s). Only --detect can yield more than one, when
// several GitButler skills share a scope; they are all refreshed together.
let agent_default_path = if custom_path.is_none() && !detect {
driving_agent.and_then(agent_default_install_path)
} 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)?View on GitHub (pinned to caf1f223d3)
Solutions
- Use an absolute path: `but skill install --path /home/me/.claude/skills`
- Use a tilde path: `but skill install --path ~/.claude/skills` (expanded to absolute)
- Add --global: `but skill install --global --path <path>`
- Run the command from inside a git repository
Example fix
$ but skill install --path skills/gb # fails outside a repo $ but skill install --path ~/.claude/skills # tilde counts as absolute
Defensive patterns
Strategy: validation
Validate before calling
let expanded = shellexpand::tilde(path).to_string(); // or manual ~ expansion
let p = std::path::Path::new(&expanded);
if !p.is_absolute() && !in_git_worktree(&cwd) {
// add --global or canonicalize: std::fs::canonicalize / absolutize against cwd
} Prevention
- Absolutize (and expand ~) before passing --path
- Treat relative --path as repo-anchored by contract
- In scripts, derive paths from a known root instead of user input
When it happens
Trigger: `cd ~ && but skill install --path skills/gitbutler` - relative path, no repo context, no --global flag.
Common situations: Install scripts run from arbitrary directories, users intending a global install but forgetting --global, automation assuming the cwd is always the repo.
Related errors
- Installation path {} is a file, not a directory. Please spec
- Cannot check local installations: not in a git repository. U
- The path {} does not exist
- The path {} is not a directory
- Path does not exist: {path}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/c826c7e8675703f3.
Report an issue: GitHub.