block/buzz · error

kick failed: {e}

Error message

kick failed: {e}

What it means

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.

Source

Thrown at crates/buzz-relay/src/handlers/report_resolution.rs:740

        "kick" => {
            let target = ctx
                .target_pubkey
                .ok_or_else(|| anyhow::anyhow!("kick requires target_pubkey"))?;
            let ch = ctx
                .channel_id
                .ok_or_else(|| anyhow::anyhow!("kick requires channel_id"))?;
            match state
                .db
                .execute_kick_with_marker(
                    action_id,
                    lease_token,
                    ctx.community_id,
                    ch,
                    target,
                    ctx.actor_pubkey,
                )
                .await
                .map_err(|e| anyhow::anyhow!("kick failed: {e}"))?
            {
                buzz_db::relay_admin_actions::KickWithMarkerResult::Removed => Ok(true),
                buzz_db::relay_admin_actions::KickWithMarkerResult::AlreadyMarked => Ok(false),
                buzz_db::relay_admin_actions::KickWithMarkerResult::AlreadyGone => Err(
                    anyhow::anyhow!("kick target was already absent before this action"),
                ),
            }
        }
        "delete" => {
            let target = ctx
                .target_event_id
                .ok_or_else(|| anyhow::anyhow!("delete requires target_event_id"))?;
            let meta = state
                .db
                .get_thread_metadata_by_event(ctx.community_id, target)
                .await
                .map_err(|e| anyhow::anyhow!("thread metadata lookup failed: {e}"))?;
            let parent_id = meta.as_ref().and_then(|m| m.parent_event_id.clone());

View on GitHub (pinned to eed74bde2f)

Solutions

  1. 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.
  2. Check Postgres logs for the wrapped `{e}` detail (deadlock, connection reset, constraint name) and fix the underlying DB issue first.
  3. Verify the deployed schema matches `migrations/` (membership + relay_admin_actions tables current).
  4. If contention-driven, confirm only one driver holds a valid lease for this `action_id`; the recovery worker picks up orphaned actions automatically.

Example fix

// before (caller)
run_atomic_mutation(state, action_id, lease_token, &ctx).await?;
// after
match run_atomic_mutation(state, action_id, lease_token, &ctx).await {
    Ok(outcome) => { /* Committed | AlreadyCommitted | LeaseLost */ }
    Err(e) if is_transient_db(&e) => schedule_retry(action_id, backoff()),
    Err(e) => return Err(anyhow::anyhow!("kick failed: {e}")),
}
Defensive patterns

Strategy: retry

Validate before calling

// ping DB before driving enforcement bursts
sqlx::query("SELECT 1").execute(&pool).await?;

Type guard

fn is_transient_db_err(e: &anyhow::Error) -> bool {
    let s = e.to_string();
    s.contains("connection") || s.contains("deadlock") || s.contains("timeout")
}

Try / catch

match run_atomic_mutation(state, action_id, lease_token, &ctx).await {
    Err(e) if is_transient_db_err(&e) => schedule_retry(action_id, backoff()),
    Err(e) => mark_action_failed(action_id, format!("kick failed: {e}")),
    Ok(_) => {}
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of block/buzz@eed74bde2f (2026-08-30). Data as JSON: /api/errors/cd424b1dfd93eac1. Report an issue: GitHub.