{"record":{"id":"c58f929017f39c2c","repo":"block/buzz","slug":"delete-failed-e","errorCode":null,"errorMessage":"delete failed: {e}","messagePattern":"delete failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-relay/src/handlers/report_resolution.rs","lineNumber":771,"sourceCode":"            let meta = state\n                .db\n                .get_thread_metadata_by_event(ctx.community_id, target)\n                .await\n                .map_err(|e| anyhow::anyhow!(\"thread metadata lookup failed: {e}\"))?;\n            let parent_id = meta.as_ref().and_then(|m| m.parent_event_id.clone());\n            let root_id = meta.as_ref().and_then(|m| m.root_event_id.clone());\n            state\n                .db\n                .execute_delete_with_marker(\n                    action_id,\n                    lease_token,\n                    ctx.community_id,\n                    target,\n                    parent_id.as_deref(),\n                    root_id.as_deref(),\n                )\n                .await\n                .map_err(|e| anyhow::anyhow!(\"delete failed: {e}\"))\n        }\n        other => Err(anyhow::anyhow!(\"unexpected enforcement action: {other}\")),\n    };\n\n    match raw? {\n        true => Ok(MutationOutcome::Committed),\n        false => {\n            // Reload to distinguish \"step_marker already set by another driver\"\n            // (AlreadyCommitted — safe to proceed to finalization) from \"this\n            // driver's lease expired\" (LeaseLost — must stop, recovery worker\n            // will take over after expiry).\n            let rec = state\n                .db\n                .get_admin_action(action_id)\n                .await\n                .map_err(|e| anyhow::anyhow!(\"classify mutation result: {e}\"))?;\n            match rec {\n                Some(r) if r.step_marker.is_some() => Ok(MutationOutcome::AlreadyCommitted),","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/crates/buzz-relay/src/handlers/report_resolution.rs#L753-L789","documentation":"This error wraps a database failure from `execute_delete_with_marker` during the \"delete\" enforcement action of report resolution (`run_atomic_mutation`). The atomic mutation tries to delete the reported event and set the action's step_marker in one lease-fenced transaction; if the DB layer returns any error (connection issue, constraint violation, row gone), it is re-wrapped with the \"delete failed: {e}\" context and propagated up through `drive_enforcement`. The inner `{e}` carries the actual Postgres/DB-layer cause.","triggerScenarios":"Calling resolve/enforcement flow where ctx.action == \"delete\" and `execute_delete_with_marker(action_id, lease_token, community_id, target_event_id, parent_id, root_id)` returns Err — e.g. Postgres connection dropped, deadlock, the target event row violating a FK during deletion, or a transaction failure inside the lease-fenced marker update.","commonSituations":"Relay DB briefly unavailable or failing over while a moderator resolves a report with 'delete content'; recovery worker re-driving an action against a DB under lock contention; parent/root thread metadata rows being concurrently mutated causing FK conflicts during thread-aware delete.","solutions":["Check the inner `{e}` message to identify the actual DB-layer cause (connectivity vs constraint vs serialization) and fix that root problem.","Verify Postgres connectivity/health of the relay's database pool (connections, timeouts, restarts).","Retry the action after the lease expires — the action recovery worker will re-drive the mutation; the lease-fenced marker makes retries safe.","If a constraint violation on parent/root, inspect `thread_metadata` rows for the target event and confirm parent/root ids match the live thread state.","Check relay logs around `drive_enforcement` for whether `raw?` failed at the mutation or the later classification step."],"exampleFix":"// before: raw anyhow error from DB layer bubbles with no context\n.execute_delete_with_marker(...).await?;\n// after: context-wrapped (as thrown) — fix at call site by matching recoverable DB errors\nlet deleted = state.db.execute_delete_with_marker(...).await\n    .map_err(|e| anyhow::anyhow!(\"delete failed: {e}\"));\nmatch deleted {\n    Ok(v) => Ok(v),\n    Err(e) if is_transient_db_error(&e) => Ok(false), // let recovery worker re-drive\n    Err(e) => Err(anyhow::anyhow!(\"delete failed: {e}\")),\n}","handlingStrategy":"retry","validationCode":"// before driving: confirm target event still exists and DB is reachable\nlet meta = state.db.get_thread_metadata_by_event(ctx.community_id, target).await\n    .map_err(|e| anyhow::anyhow!(\"pre-check thread metadata: {e}\"))?;\nif is_transient_db_error(&e) { schedule_retry_after_lease_expiry(action_id); }","typeGuard":"fn is_transient_db_error(e: &anyhow::Error) -> bool {\n    let s = format!(\"{e:#}\");\n    [\"connection\", \"timeout\", \"closed\", \"pool\"].iter().any(|k| s.contains(k))\n}","tryCatchPattern":"match run_atomic_mutation(ctx).await {\n    Ok(outcome) => proceed_with_finalization(outcome),\n    Err(e) if is_transient_db_error(&e) => log_and_defer_to_recovery_worker(ctx.action_id, e),\n    Err(e) => return Err(e), // permanent: surface to moderator\n}","preventionTips":["Rely on the lease-fenced marker design: failed deletes are safe to re-drive after lease expiry — prefer deferral over inline retry loops.","Monitor Postgres health and connection-pool saturation on the relay.","Keep thread_metadata (parent/root ids) consistent before issuing delete enforcement.","Alert on 'delete failed' log lines to catch DB degradation early."],"tags":["database","postgresql","moderation","transaction","rust"],"backgroundTag":"database-transaction-failed","analyzedSha":"eed74bde2f4797714335ac10c56c0b0244c1def4","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}