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

  1. Use an absolute path: `but skill install --path /home/me/.claude/skills`
  2. Use a tilde path: `but skill install --path ~/.claude/skills` (expanded to absolute)
  3. Add --global: `but skill install --global --path <path>`
  4. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/c826c7e8675703f3. Report an issue: GitHub.