gitbutlerapp/gitbutler · error

Cannot check local installations: not in a git repository. U

Error message

Cannot check local installations: not in a git repository.
Use --global to check global installations, or run from within a repository.

What it means

Thrown by check_skills (backs `but skill status`/`but skill update`) when --local is passed but no git repository context exists. Local skill installations live inside the current repository, so without a repo there is no local scope to inspect; the command fails fast instead of silently reporting nothing. Only the explicit --local flag triggers this - the default (both scopes) degrades gracefully.

Source

Thrown at crates/but/src/command/skill/mod.rs:682

fn check_skills(
    mut ctx: Option<&mut Context>,
    out: &mut OutputChannel,
    global_only: bool,
    local_only: bool,
    auto_update: bool,
) -> Result<()> {
    let t = theme::get();
    // Determine scope
    let (check_global, check_local) = match (global_only, local_only) {
        (true, false) => (true, false),
        (false, true) => (false, true),
        (false, false) => (true, true), // default: check both
        _ => unreachable!(),            // clap conflicts_with prevents this
    };

    // Warn if --local was explicitly requested but no repo context is available
    if local_only && ctx.is_none() {
        anyhow::bail!(
            "Cannot check local installations: not in a git repository.\n\
             Use --global to check global installations, or run from within a repository."
        );
    }

    // First check to find outdated skills (reborrow ctx so we can use it again later)
    let initial_result = check_skill_status(ctx.as_deref_mut(), check_global, check_local)?;

    // Collect paths of outdated skills (needed for auto-update)
    let outdated_paths: Vec<String> = initial_result
        .skills
        .iter()
        .filter(|s| !s.up_to_date)
        .map(|s| s.path.display().to_string())
        .collect();

    // Auto-update if requested (do this before displaying results)
    if auto_update && !outdated_paths.is_empty() {

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Run the command from inside the target git repository
  2. Use `but skill status --global` to check only user-level installations
  3. Drop --local and run the plain command, which still checks the global scope without a repo

Example fix

# before (fails outside a repo)
$ but skill status --local
# after
$ cd ~/my-repo && but skill status --local
# or
$ but skill status --global
Defensive patterns

Strategy: validation

Validate before calling

fn in_git_worktree(dir: &std::path::Path) -> bool {
    gix::discover(dir).ok().and_then(|r| r.workdir().map(|_| true)).unwrap_or(false)
}
// before passing --local:
if !in_git_worktree(&cwd) { /* use --global instead of --local */ }

Prevention

When it happens

Trigger: Running `but skill status --local` or `but skill update --local` from a directory that gix::discover cannot resolve to a git worktree, leaving ctx = None while local_only = true.

Common situations: Running from $HOME or /tmp, CI jobs that never cloned the repo, moving a project directory without its .git folder, shell aliases that execute but from arbitrary directories.

Related errors


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