{"record":{"id":"cd424b1dfd93eac1","repo":"block/buzz","slug":"kick-failed-e","errorCode":null,"errorMessage":"kick failed: {e}","messagePattern":"kick failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-relay/src/handlers/report_resolution.rs","lineNumber":740,"sourceCode":"        \"kick\" => {\n            let target = ctx\n                .target_pubkey\n                .ok_or_else(|| anyhow::anyhow!(\"kick requires target_pubkey\"))?;\n            let ch = ctx\n                .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());","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/crates/buzz-relay/src/handlers/report_resolution.rs#L722-L758","documentation":"The kick's atomic DB mutation (`execute_kick_with_marker`) returned a SQL/database error, which the handler wraps as `kick failed: {e}`. This runs inside the single transaction that performs the member removal AND sets `step_marker = 'mutation_committed'`, fenced by `action_id` + `lease_token`, so any constraint violation, deadlock, or connection problem rolls back both writes and surfaces here.","triggerScenarios":"1) `execute_kick_with_marker` hits a Postgres error: connection drop, deadlock, serialization failure, or a constraint/trigger error in the membership or admin-action tables. 2) Long transactions push the connection past statement timeouts. 3) Connection-pool exhaustion under concurrent enforcement drivers.","commonSituations":"Transient Postgres restarts or pool exhaustion under load; schema drift where membership/admin-action tables lack expected rows or triggers; concurrent drivers contending on the same action row; slow disk causing statement timeouts.","solutions":["Retry the action once the lease is valid — enforcement is idempotent and fenced by `action_id`/`lease_token`, so retries after transient DB errors are safe.","Check Postgres logs for the wrapped `{e}` detail (deadlock, connection reset, constraint name) and fix the underlying DB issue first.","Verify the deployed schema matches `migrations/` (membership + relay_admin_actions tables current).","If contention-driven, confirm only one driver holds a valid lease for this `action_id`; the recovery worker picks up orphaned actions automatically."],"exampleFix":"// before (caller)\nrun_atomic_mutation(state, action_id, lease_token, &ctx).await?;\n// after\nmatch run_atomic_mutation(state, action_id, lease_token, &ctx).await {\n    Ok(outcome) => { /* Committed | AlreadyCommitted | LeaseLost */ }\n    Err(e) if is_transient_db(&e) => schedule_retry(action_id, backoff()),\n    Err(e) => return Err(anyhow::anyhow!(\"kick failed: {e}\")),\n}","handlingStrategy":"retry","validationCode":"// ping DB before driving enforcement bursts\nsqlx::query(\"SELECT 1\").execute(&pool).await?;","typeGuard":"fn is_transient_db_err(e: &anyhow::Error) -> bool {\n    let s = e.to_string();\n    s.contains(\"connection\") || s.contains(\"deadlock\") || s.contains(\"timeout\")\n}","tryCatchPattern":"match run_atomic_mutation(state, action_id, lease_token, &ctx).await {\n    Err(e) if is_transient_db_err(&e) => schedule_retry(action_id, backoff()),\n    Err(e) => mark_action_failed(action_id, format!(\"kick failed: {e}\")),\n    Ok(_) => {}\n}","preventionTips":["Run `just test` (Postgres-backed integration tests) after touching buzz-db paths.","Keep transactions short — do the metadata lookup close to the mutation.","Monitor pool saturation and statement timeouts in production Postgres metrics.","Ensure migrations run before the relay binary starts serving enforcement."],"tags":["postgres","database","enforcement","transaction"],"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-14T00:17:10.932Z"}