gitbutlerapp/gitbutler · error

Worktree has no checkout recorded in the editor

Error message

Worktree {worktree_name} has no checkout recorded in the editor

What it means

The graph rebase editor records a checkout (name, ref, head) for each visible worktree when created. When a caller later sets a merge-base override by worktree name, the editor searches its recorded worktrees and bails if no checkout with that exact name exists. This indicates a stale or misspelled worktree name relative to the editor's snapshot.

Solutions

  1. List the editor's recorded worktree checkouts and use an exact recorded name
  2. Recreate the editor (create_with_opts) so its worktree snapshot includes the worktree
  3. Verify the worktree still exists (`git worktree list`) and its name matches exactly before calling

Example fix

// before
editor.set_worktree_merge_base_override("feature-x", tree_id)?;
// after
if editor.worktree_names().contains(&"feature-x".into()) {
    editor.set_worktree_merge_base_override("feature-x", tree_id)?;
}
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(
    editor.worktree_names().iter().any(|n| n == worktree_name),
    "worktree {} not recorded in this editor", worktree_name
);

Try / catch

match editor.set_worktree_merge_base_override(name, tree_id) {
    Ok(()) => {},
    Err(e) if e.to_string().contains("no checkout recorded") => {
        // recreate editor to pick up current worktrees, then retry
        let editor = create_with_opts(&workspace, &tips, opts)?;
        editor.set_worktree_merge_base_override(name, tree_id)?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `set_worktree_merge_base_override` with a `worktree_name` that was never recorded (worktree created after the editor, removed before, or name mismatch e.g. different casing/branch vs worktree name).

Common situations: A worktree was added or pruned between editor creation and the override call; passing a branch name where a worktree name is expected; typos in worktree names constructed programmatically.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/but-rebase/src/graph_rebase/commit.rs:61

    /// before mutating the step graph.
    pub fn set_worktree_merge_base_override(
        &mut self,
        worktree_name: &gix::bstr::BStr,
        tree_id: gix::ObjectId,
    ) -> Result<()> {
        for checkout in &mut self.checkouts {
            if let super::Checkout::Worktree {
                worktree_name: name,
                merge_base_override,
                ..
            } = checkout
                && name == worktree_name
            {
                *merge_base_override = Some(tree_id);
                return Ok(());
            }
        }
        bail!("Worktree {worktree_name} has no checkout recorded in the editor")
    }

    /// Finds a commit from inside the editor's in memory repository.
    pub fn find_commit(&self, id: gix::ObjectId) -> Result<but_core::CommitOwned> {
        but_core::Commit::from_id(id.attach(&self.repo)).map(|c| c.detach())
    }

    /// Finds a commit that is selectable in the editor graph and is
    /// found in the editor's repo.
    ///
    /// Returns the normalized selector and the found commit.
    pub fn find_selectable_commit(
        &self,
        selector: impl ToCommitSelector,
    ) -> Result<(Selector, but_core::CommitOwned)> {
        let selector = self
            .history
            .normalize_selector(selector.to_commit_selector(self)?)?;

View on GitHub (pinned to 58e5313667)