gitbutlerapp/gitbutler · error · anyhow::Error

No comment with id {id}

Error message

No comment with id {id}

What it means

update_payload() searches the comment store for the given id inside store.update() and bails when no comment matches. Ids are caller-supplied strings, so this is a plain not-found against persisted CommentStore state (including archived comments — they are found but rejected separately).

Source

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

pub struct Listing {
    /// The re-anchored, unarchived comments.
    pub comments: Vec<DiffComment>,
    /// Whether the listing wrote to the store (persisted drift, auto-archived comments, or
    /// purged old archived rows). Callers that bridge processes can use this to notify other
    /// consumers of the store.
    pub persisted_changes: bool,
}

/// Replace the payload of the unarchived comment with the given `id`.
pub fn update_payload(
    store: &CommentStore,
    id: &str,
    payload: String,
    now_ms: i64,
) -> anyhow::Result<()> {
    store.update(|comments| {
        let Some(comment) = comments.iter_mut().find(|c| c.id == id) else {
            bail!("No comment with id {id}");
        };
        if comment.archived_at_ms.is_some() {
            bail!("Comment {id} is archived and cannot be updated");
        }
        comment.payload = payload;
        comment.updated_at_ms = now_ms;
        Ok(())
    })
}

/// Archive the comment with the given `id`, hiding it from all future listings.
/// Returns `false` if the comment does not exist or was already archived.
pub fn archive_comment(store: &CommentStore, id: &str, now_ms: i64) -> anyhow::Result<bool> {
    store.update(|comments| {
        Ok(
            match comments
                .iter_mut()
                .find(|c| c.id == id && c.archived_at_ms.is_none())

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Re-list comments from the same store and use the current id
  2. Verify the store path is identical to the one used at creation (same repo/workspace)
  3. Treat not-found as benign in edit flows: refresh the view and let the user re-create the comment
  4. Sanitize ids end-to-end so they survive serialization unchanged
Defensive patterns

Strategy: validation

Validate before calling

// verify the id against the same store before updating
let exists = store.with(|comments| comments.iter().any(|c| c.id == id))?;
anyhow::ensure!(exists, "comment {id} not in this store — refresh the listing");

Try / catch

match but_comments::update_payload(&store, id, payload, now) {
    Err(e) if e.to_string().contains("No comment with id") =>
        refresh_and_recreate(&store, payload).await, // self-heal stale edits
    r => r?,
}

Prevention

When it happens

Trigger: Calling update_payload with an id from a stale listing, a typo'd/truncated id, or against a different CommentStore file than the one the comment was created in.

Common situations: UI editing a comment deleted in another session/window; id round-tripped through serialization losing characters; store path changed between create and update (different repo/workspace directory).

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@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/9dd4c8162a00ac8f. Report an issue: GitHub.