gitbutlerapp/gitbutler · error
Repository has no working directory
Error message
Repository has no working directory
What it means
Thrown by `setup_local_remote` when no push remote is configured anywhere, so setup tries to fabricate a `gb-local` remote pointing at the repository itself. The remote URL is derived from `repo.workdir()`; on a bare repository (or a repo opened without a worktree) `workdir()` is None and this error is returned before any config is written.
Source
Thrown at crates/but/src/command/legacy/setup.rs:538
if ws.remote_name().is_none()
&& repo
.remote_default_name(gix::remote::Direction::Push)
.is_none()
{
anyhow::bail!(
"Neither found push remote found in workspace nor unambiguously in the Git repository configuration."
)
};
Ok(true)
}
/// Creates a 'gb-local' remote pointing to this repository and creates tracking refs for the default branch.
fn setup_local_remote(repo: &gix::Repository, out: &mut OutputChannel) -> anyhow::Result<String> {
let t = theme::get();
let repo_url = repo
.workdir()
.ok_or_else(|| anyhow::anyhow!("Repository has no working directory"))?
.to_str()
.ok_or_else(|| anyhow::anyhow!("Repository path is not valid UTF-8"))?;
if let Some(out) = out.for_human() {
writeln!(
out,
" {}",
t.info
.paint("No push remote found, creating gb-local remote...")
)?;
}
edit_repo_config(repo, gix::config::Source::Local, |config| {
let mut section = config.section_mut_or_create_new("remote", Some("gb-local".into()))?;
section.push("url", repo_url)?;
Ok(())
})?;
View on GitHub (pinned to caf1f223d3)
Solutions
- Run setup from a non-bare working clone of the repository instead
- Configure a real push remote before setup so the gb-local fallback is never needed: `git remote add origin <url> && git push -u origin HEAD`
- If you must work where you are, create a worktree-style clone next to the bare repo and register that
Example fix
# before: bare repo, no push remote cd /srv/git/project.git && but setup # after: give it a remote to use git -C /srv/git/project.git remote add origin git@example.com:project.git but setup /srv/git/project.git
Defensive patterns
Strategy: validation
Validate before calling
let repo = gix::open(&repo_path)?;
let Some(workdir) = repo.workdir() else {
anyhow::bail!("no working directory; configure a push remote or use a non-bare clone");
};
if workdir.to_str().is_none() {
anyhow::bail!("workdir path is not valid UTF-8; move the repo");
} Try / catch
match setup_local_remote(&repo, &mut out) {
Ok(remote) => { /* use remote */ }
Err(err) if err.to_string().contains("no working directory") => {
// add a real push remote instead of the gb-local fallback
}
Err(err) => return Err(err),
} Prevention
- Configure origin (and a pushurl) before running setup so gb-local is never needed
- Always run setup from a non-bare working clone
- Check `git rev-parse --is-bare-repository` in provisioning scripts
When it happens
Trigger: Running `but setup` in a bare repository (or worktree-less core) that also has no push remote configured in the workspace or git config — the gb-local fallback path is taken and immediately fails on the missing workdir.
Common situations: Setting up tooling inside a bare central repo on a server; CI jobs that check out with unusual git dir layouts; a workspace config that lost its remote entries.
Related errors
- The repository at {} is bare. GitButler requires a non-bare
- The repository at {} is a non-main worktree. GitButler requi
- The repository at {} has no working directory. GitButler req
- The repository at {} has no .git directory. GitButler requir
- The repository at {} uses the currently unsupported reftable
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/8e3f82b058dcce8a.
Report an issue: GitHub.