{"record":{"id":"b6a22f6c67c52a47","repo":"block/buzz","slug":"kick-target-was-already-absent-before-this-action","errorCode":null,"errorMessage":"kick target was already absent before this action","messagePattern":"kick target was already absent before this action","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/buzz-relay/src/handlers/report_resolution.rs","lineNumber":745,"sourceCode":"                .channel_id\n                .ok_or_else(|| anyhow::anyhow!(\"kick requires channel_id\"))?;\n            match state\n                .db\n                .execute_kick_with_marker(\n                    action_id,\n                    lease_token,\n                    ctx.community_id,\n                    ch,\n                    target,\n                    ctx.actor_pubkey,\n                )\n                .await\n                .map_err(|e| anyhow::anyhow!(\"kick failed: {e}\"))?\n            {\n                buzz_db::relay_admin_actions::KickWithMarkerResult::Removed => Ok(true),\n                buzz_db::relay_admin_actions::KickWithMarkerResult::AlreadyMarked => Ok(false),\n                buzz_db::relay_admin_actions::KickWithMarkerResult::AlreadyGone => Err(\n                    anyhow::anyhow!(\"kick target was already absent before this action\"),\n                ),\n            }\n        }\n        \"delete\" => {\n            let target = ctx\n                .target_event_id\n                .ok_or_else(|| anyhow::anyhow!(\"delete requires target_event_id\"))?;\n            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,","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/crates/buzz-relay/src/handlers/report_resolution.rs#L727-L763","documentation":"`execute_kick_with_marker` returned `KickWithMarkerResult::AlreadyGone`: the target pubkey was not a member of the channel even before this action ran, so there is nothing to kick. The handler treats this as `Err` (rather than a benign no-op like `AlreadyMarked`) because a kick resolved from a report should have had a member to remove — the target's absence usually means state changed between report and enforcement.","triggerScenarios":"1) The reported user already left the channel (voluntarily or via an earlier ban/kick) before this action's driver ran. 2) Duplicate enforcement attempts racing: one driver committed the kick+marker; a later/parallel driver sees the member gone and hits this branch instead of `AlreadyMarked`. 3) The recovery worker re-drives an action after another path removed the membership row without setting the step marker.","commonSituations":"Race between a user self-removing and an admin resolving the report; concurrent duplicate report resolutions against the same target; manual DB cleanup of membership rows; relay restarts where the recovery worker replays actions after another driver finished the mutation outside the fenced transaction.","solutions":["Inspect `relay_admin_actions` for this `action_id` and the channel's membership history: if the kick already took effect, mark the action resolved/finalized instead of re-driving it.","If it is a benign race (target already gone), downgrade handling: treat `AlreadyGone` as a completed outcome, or pre-check membership before claiming a lease.","Prevent manual membership edits during active enforcement windows.","If it recurs, check whether multiple `drive_enforcement` instances (HTTP driver + recovery worker) both claim actions and confirm lease fencing works."],"exampleFix":"// before\nKickWithMarkerResult::AlreadyGone => Err(anyhow::anyhow!(\"kick target was already absent before this action\")),\n// after\nKickWithMarkerResult::AlreadyGone => {\n    tracing::info!(%action_id, \"kick target already absent; treating as done\");\n    Ok(true)\n}","handlingStrategy":"try-catch","validationCode":"// pre-check membership before resolving a kick\nlet is_member = state.db.is_channel_member(community_id, channel_id, target).await?;\nanyhow::ensure!(is_member, \"target already absent from channel; skip kick\");","typeGuard":"fn is_already_gone(err: &anyhow::Error) -> bool {\n    err.to_string().contains(\"kick target was already absent\")\n}","tryCatchPattern":"match run_atomic_mutation(state, action_id, lease_token, &ctx).await {\n    Err(e) if is_already_gone(&e) => {\n        tracing::info!(%action_id, \"kick no-op: target already gone\");\n        finalize_as_noop(action_id).await?;\n    }\n    other => other?,\n}","preventionTips":["Treat kick as idempotent at the product level: absence is often a legitimate outcome.","Check for concurrent drivers on the same action_id before re-driving.","Avoid manual membership-table edits during enforcement windows.","Track action lifecycle (step_marker) so replays are classified, not re-executed blindly."],"tags":["race-condition","enforcement","nostr","idempotency"],"backgroundTag":"enforcement-target-already-gone","analyzedSha":"eed74bde2f4797714335ac10c56c0b0244c1def4","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}