gitbutlerapp/gitbutler · warning · anyhow::Error

Nothing to anchor a comment to in {scope}

Error message

Nothing to anchor a comment to in {scope}

What it means

create_comment() mapped the file anchor to FileAnchor::Gone, meaning the diff knows about the file but there is no line content on any side to attach the comment to — typically a deleted file with nothing to anchor against. The {scope} placeholder shows commit/path context to identify which anchor failed.

Source

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

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(),
            )
        })?;

    // Snapshot the same-side neighbouring lines too: they disambiguate between identical
    // lines when the comment is re-located later.
    let line_before = (comment.line_number > 1)
        .then(|| file.line_at(comment.side, comment.line_number - 1))

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Anchor the comment to the side where the file still has content (e.g. the old side of a deletion)
  2. If the file is genuinely gone in both displayed sides, use a commit-level/file-level note instead of a line anchor
  3. Re-open the diff so the UI recomputes line numbers from the current hunk before submitting
  4. Increase context_lines when constructing ScopeDiffs so adjacent hunks provide anchorable lines
Defensive patterns

Strategy: validation

Validate before calling

// probe the anchor before submitting
let mut diffs = ScopeDiffs::new(repo, workspace, context_lines);
match diffs.file(comment.commit_change_id.as_deref(), &comment.path)? {
    Some(FileAnchor::Lines(_)) => { /* safe to create the line comment */ }
    Some(FileAnchor::Gone) => return Err(anyhow!("file has no lines on this side")),
    Some(FileAnchor::Unanchorable) => return Err(anyhow!("binary or oversized diff")),
    None => return Err(anyhow!("commit not in applied workspace")),
}

Try / catch

// map to UI guidance rather than a raw error
match create_comment(...) {
    Err(e) if e.to_string().contains("Nothing to anchor") =>
        show_hint("pick a line on the side where the file exists"),
    r => r?,
}

Prevention

When it happens

Trigger: Anchoring a line comment to a file that the commit deletes, or to a side where the file does not exist (e.g. old-side line numbers of an added file after the diff drifted), so no line range can be produced.

Common situations: Review UIs pre-filling line numbers from a stale diff; commenting on deleted files during code review; diff context_lines too small to surface any hunk for the selected side.

Related errors


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