block/buzz · warning

kick target was already absent before this action

Error message

kick target was already absent before this action

What it means

`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.

Source

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

                .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());
            let root_id = meta.as_ref().and_then(|m| m.root_event_id.clone());
            state
                .db
                .execute_delete_with_marker(
                    action_id,

View on GitHub (pinned to eed74bde2f)

Solutions

  1. 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.
  2. 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.
  3. Prevent manual membership edits during active enforcement windows.
  4. If it recurs, check whether multiple `drive_enforcement` instances (HTTP driver + recovery worker) both claim actions and confirm lease fencing works.

Example fix

// before
KickWithMarkerResult::AlreadyGone => Err(anyhow::anyhow!("kick target was already absent before this action")),
// after
KickWithMarkerResult::AlreadyGone => {
    tracing::info!(%action_id, "kick target already absent; treating as done");
    Ok(true)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check membership before resolving a kick
let is_member = state.db.is_channel_member(community_id, channel_id, target).await?;
anyhow::ensure!(is_member, "target already absent from channel; skip kick");

Type guard

fn is_already_gone(err: &anyhow::Error) -> bool {
    err.to_string().contains("kick target was already absent")
}

Try / catch

match run_atomic_mutation(state, action_id, lease_token, &ctx).await {
    Err(e) if is_already_gone(&e) => {
        tracing::info!(%action_id, "kick no-op: target already gone");
        finalize_as_noop(action_id).await?;
    }
    other => other?,
}

Prevention

When it happens

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

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

Related errors


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