{"record":{"id":"3ff44b36d737f93a","repo":"gitbutlerapp/gitbutler","slug":"comment-id-is-archived-and-cannot-be-updated","errorCode":null,"errorMessage":"Comment {id} is archived and cannot be updated","messagePattern":"Comment (.+?) is archived and cannot be updated","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/but-comments/src/lib.rs","lineNumber":350,"sourceCode":"    /// Whether the listing wrote to the store (persisted drift, auto-archived comments, or\n    /// purged old archived rows). Callers that bridge processes can use this to notify other\n    /// consumers of the store.\n    pub persisted_changes: bool,\n}\n\n/// Replace the payload of the unarchived comment with the given `id`.\npub fn update_payload(\n    store: &CommentStore,\n    id: &str,\n    payload: String,\n    now_ms: i64,\n) -> anyhow::Result<()> {\n    store.update(|comments| {\n        let Some(comment) = comments.iter_mut().find(|c| c.id == id) else {\n            bail!(\"No comment with id {id}\");\n        };\n        if comment.archived_at_ms.is_some() {\n            bail!(\"Comment {id} is archived and cannot be updated\");\n        }\n        comment.payload = payload;\n        comment.updated_at_ms = now_ms;\n        Ok(())\n    })\n}\n\n/// Archive the comment with the given `id`, hiding it from all future listings.\n/// Returns `false` if the comment does not exist or was already archived.\npub fn archive_comment(store: &CommentStore, id: &str, now_ms: i64) -> anyhow::Result<bool> {\n    store.update(|comments| {\n        Ok(\n            match comments\n                .iter_mut()\n                .find(|c| c.id == id && c.archived_at_ms.is_none())\n            {\n                Some(comment) => {\n                    comment.archived_at_ms = Some(now_ms);","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-comments/src/lib.rs#L332-L368","documentation":"update_payload() found the comment with the given id but its archived_at_ms is set, so the store refuses to modify it. Archived comments are hidden from listings, yet still physically present, which is why update lands here instead of the not-found branch.","triggerScenarios":"Updating a comment that was archived earlier via archive_comment(), typically from a UI that still shows a stale (pre-archive) view and lets the user edit it.","commonSituations":"Two windows open on the same review; one archives, the other submits an edit; clients replaying offline edits after a sync archived the comment.","solutions":["Refresh the comment listing (archived entries are excluded) so stale edits cannot be submitted","If the edit matters, un-archive/restore the comment first if such an API exists, or re-create it","Guard edit UIs by checking archived state from the fresh listing before enabling save","Treat this error as a soft conflict: notify the user the comment no longer exists actively"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// check archived state from the live store before enabling edit\nlet active = store.with(|comments| comments.iter()\n    .find(|c| c.id == id).map(|c| c.archived_at_ms.is_none()))?;\nanyhow::ensure!(active == Some(true), \"comment {id} is archived\");","typeGuard":null,"tryCatchPattern":"match but_comments::update_payload(&store, id, payload, now) {\n    Err(e) if e.to_string().contains(\"archived\") =>\n        notify(\"this comment was archived elsewhere — edit discarded\"),\n    r => r?,\n}","preventionTips":["Hide archived comments from edit affordances immediately after archive actions","Reload comment state when the window regains focus","Treat archived-update as a conflict signal, not a hard failure"],"tags":["comments","archived","store","conflict"],"backgroundTag":"archived-record-modification","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}