gitbutlerapp/gitbutler · error · anyhow::Error

Commit {} is not in the applied workspace

Error message

Commit {} is not in the applied workspace

What it means

create_comment() calls ScopeDiffs::file(commit_change_id, path) to locate the file to anchor to; when it returns None, the commit identified by that change-id is not part of the applied workspace the diff was computed from, and the comment cannot be located. The change-id (not a raw sha) is the workspace's stable handle for a commit, so this specifically means 'that change is not applied right now'.

Source

Thrown at crates/but-comments/src/lib.rs:131

/// Create a new comment anchored to a line in a diff.
///
/// The anchor must point at a line that exists in the current diff — the uncommitted worktree
/// diff of `path`, or the first-parent diff of the workspace commit with `commit_change_id` —
/// otherwise an error is returned. The anchored line's content (and its neighbours) is
/// snapshotted so the comment can be re-located when the diff drifts.
pub fn create_comment(
    repo: &gix::Repository,
    workspace: &but_graph::Workspace,
    store: &CommentStore,
    comment: NewComment,
    context_lines: u32,
    now_ms: i64,
) -> anyhow::Result<DiffComment> {
    let scope = anchor_scope_display(&comment.commit_change_id, &comment.path);
    let mut diffs = ScopeDiffs::new(repo, workspace, context_lines);
    let Some(anchor) = diffs.file(comment.commit_change_id.as_deref(), &comment.path)? else {
        bail!(
            "Commit {} is not in the applied workspace",
            comment.commit_change_id.as_deref().unwrap_or_default()
        );
    };
    let file = match anchor {
        FileAnchor::Lines(lines) => lines,
        FileAnchor::Gone => bail!("Nothing to anchor a comment to in {scope}"),
        FileAnchor::Unanchorable => {
            bail!("Cannot comment on {scope}: the diff is binary or too large")
        }
    };
    let line = file
        .line_at(comment.side, comment.line_number)
        .with_context(|| {
            format!(
                "No line {} on the {} side in {scope}",
                comment.line_number,
                comment.side.as_str(),

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Refresh the workspace and re-create the comment against the commit's current change-id
  2. Re-apply the unapplied commit so it is part of the applied workspace, then comment
  3. If the commit was rewritten, look up its new change-id from the current workspace before commenting
  4. Guard callers to re-resolve change-ids right before create_comment instead of caching them

Example fix

// before: change-id captured earlier, may be unapplied now
but_comments::create_comment(&repo, &workspace, &store, comment, 3, 0, now)?;

// after: re-resolve against the live workspace first
let applied: Vec<_> = workspace.applied_change_ids();
anyhow::ensure!(applied.contains(&comment.commit_change_id), "commit no longer applied");
but_comments::create_comment(&repo, &workspace, &store, comment, 3, 0, now)?;
Defensive patterns

Strategy: validation

Validate before calling

// confirm the change-id is currently applied before creating the comment
let applied: Vec<_> = workspace.applied_commits().iter().map(|c| c.change_id().to_owned()).collect();
anyhow::ensure!(
    comment.commit_change_id.as_ref().is_some_and(|id| applied.contains(id)),
    "commit no longer in the applied workspace"
);

Try / catch

match but_comments::create_comment(&repo, &ws, &store, comment.clone(), 3, 0, now) {
    Err(e) if e.to_string().contains("not in the applied workspace") =>
        Err(anyhow!("comment target drifted — refresh and retry")),
    r => r?,
}

Prevention

When it happens

Trigger: Creating a diff comment for a commit that was unapplied/archived from the workspace, whose change-id went stale after a rebase rewrote the commit, or when the caller builds the request from a UI state older than the current workspace.

Common situations: User opens a diff, the workspace is reorganized (unapply/rebase/order change) in another window or by a teammate's sync, then the user hits 'comment'; automation replaying stored change-ids after history rewrites.

Related errors


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