gitbutlerapp/gitbutler · error

Can only open the GUI on directories

Error message

Can only open the GUI on directories: '{not_dir}'

What it means

`but gui` opens the desktop app pointed at a project directory, relying on registered URL schemes per release channel. `open` validates that the given path is actually a directory and bails with the offending path if not, since the GUI can only be launched against a project/worktree directory.

Solutions

  1. Pass the repository root directory (or a directory inside it) instead of a file
  2. Verify the path exists and is a directory: test -d <path>
  3. Recreate or re-clone the directory if it was deleted/moved

Example fix

// before
but gui ~/repos/myproj/README.md
// after
but gui ~/repos/myproj
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('node:fs');
function assertIsDirectory(p) {
  if (!fs.statSync(p).isDirectory()) throw new Error(`Not a directory: ${p}`);
}
// call before: but gui <path>

Type guard

const isDir = (p) => { try { return require('node:fs').statSync(p).isDirectory(); } catch { return false; } };

Try / catch

try {
  await openGui(projectPath);
} catch (e) {
  if (e.message.includes('Can only open the GUI on directories')) {
    console.error(`Pass the repo directory, not: ${projectPath}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Running `but gui <path>` where path is a regular file, a broken symlink, a non-existent path, or a typo; also passing a deleted directory that was removed after shell completion cached it.

Common situations: Tab-completing onto a file instead of the repo folder; passing the repo's README or a subfile; running from a stale shell whose cwd directory was deleted; typos in the path.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/25348414763d339b. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/command/gui.rs:11

use anyhow::{Context as _, Result};
use but_path::AppChannel;

/// Open the GitButler GUI application for `possibly_project_dir`,
/// which must be a directory or trigger an error.
///
/// This expects that the GUI application is present and has correctly registered URL
/// schemes for the different channels.
pub fn open(possibly_project_dir: &std::path::Path, new_window: bool) -> Result<()> {
    if !possibly_project_dir.is_dir() {
        anyhow::bail!(
            "Can only open the GUI on directories: '{not_dir}'",
            not_dir = possibly_project_dir.display()
        );
    }

    let channel = AppChannel::new();
    let absolute_path = std::fs::canonicalize(possibly_project_dir).with_context(|| {
        format!(
            "Failed to canonicalize path before opening the GUI: {}",
            possibly_project_dir.display()
        )
    })?;
    channel.open(&absolute_path, new_window)?;
    Ok(())
}

View on GitHub (pinned to 58e5313667)