gitbutlerapp/gitbutler · error
Cannot currently work in repositories without a worktree
Error message
Cannot currently work in repositories without a worktree
What it means
Context::workdir_or_fail returns the repository's working directory, but bare repositories have none. The library cannot run worktree-dependent operations (file lookups, workspace commands) without a checkout, so it raises this anyhow error with code NOT_AUTHENTICATED-style plain message. It exists precisely to fail fast with a clear message instead of returning None.
Solutions
- Use a non-bare working clone of the repository
- If you must work with a bare repo, clone it to a working directory first and point but there
- Guard calls with a check for a worktree (repo.workdir().is_some()) and skip worktree-dependent operations otherwise
Example fix
// before
let dir = ctx.workdir_or_fail()?;
find_files(&ctx)?;
// after
let dir = match ctx.repo.get()?.workdir() {
Some(_) => ctx.workdir_or_fail()?,
None => anyhow::bail!("this command needs a checked-out worktree"),
}; Defensive patterns
Strategy: fallback
Validate before calling
if ctx.repo.get()?.workdir().is_none() {
bail!("operation requires a checked-out worktree");
} Type guard
fn has_worktree(ctx: &Context) -> bool { ctx.repo.get().ok().and_then(|r| r.workdir()).is_some() } Try / catch
match ctx.workdir_or_fail() {
Ok(dir) => use(dir),
Err(e) if e.to_string().contains("without a worktree") => clone_working_copy()?,
Err(e) => return Err(e),
} Prevention
- Never point but at bare repositories or bare --git-dir paths
- Clone with a working tree for interactive/worktree operations
- Skip worktree-dependent features in server-side automation
When it happens
Trigger: Calling workdir_or_fail (via set_active, handle_command_confirm, find_files, etc.) on a Context whose repository is bare (repo.workdir() returns None) — e.g. pointing but at a bare repo path or a repo opened via gitdir.
Common situations: Running `but` commands inside a bare repository or a --bare clone; automation that opens the .git directory directly; server-side repo paths without a checkout.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot currently work in repositories without a worktree
- Bare repositories are not supported.
- bare repositories are not supported
- `but setup` cannot run from a linked worktree; run it from…
- Cannot hash directory entries that aren't files or symlinks
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/0f2b5fc6b7594131.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-ctx/src/lib.rs:1002
/// Fallible as it may need to open a repository.
pub fn workdir_or_gitdir(&self) -> anyhow::Result<PathBuf> {
let repo = self.repo.get()?;
Ok(repo.workdir().unwrap_or(repo.git_dir()).to_owned())
}
/// Return the worktree directory associated with the context Git [repository](Self::repo).
pub fn workdir(&self) -> anyhow::Result<Option<PathBuf>> {
self.repo.get().map(|repo| repo.workdir().map(Into::into))
}
/// Return the worktree directory associated with the context Git [repository](Self::repo),
/// or fail.
///
/// # Try to gracefully degrade if there is no worktree!
pub fn workdir_or_fail(&self) -> anyhow::Result<PathBuf> {
let repo = self.repo.get()?;
repo.workdir()
.ok_or_else(|| anyhow!("Cannot currently work in repositories without a worktree"))
.map(Into::into)
}
}
/// *Repository* helpers, for when you need something more specific than [Self::repo].
impl Context {
/// Open an isolated repository, one that didn't read options beyond `.git/config` and
/// knows no environment variables.
///
/// Use it for fastest-possible access, when incomplete configuration is acceptable.
/// Note that [Self::repo].get() should be preferred.
pub fn open_isolated_repo(&self) -> anyhow::Result<gix::Repository> {
Ok(gix::open_opts(
&self.gitdir,
gix::open::Options::isolated(),
)?)
}
View on GitHub (pinned to 58e5313667)