block/buzz · error

ban requires target_pubkey

Error message

ban requires target_pubkey

What it means

Inside `run_atomic_mutation` (driven by `drive_enforcement`), the 'ban' arm of the action match requires the mutation context `ctx.target_pubkey` to be `Some`. If it is `None`, the enforcement action cannot identify which user to ban, so the atomic transaction aborts with this error rather than executing a ban against an unknown target.

Source

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

/// - [`MutationOutcome::Committed`] — this driver committed the marker.
/// - [`MutationOutcome::AlreadyCommitted`] — another driver set the marker first.
/// - [`MutationOutcome::LeaseLost`] — the caller's lease has expired; the caller
///   must stop and let the recovery worker take over.
/// - `Err` — the mutation itself failed (DB or validation error).
async fn run_atomic_mutation(
    state: &Arc<AppState>,
    action_id: Uuid,
    lease_token: Uuid,
    ctx: &EnforcementCtx<'_>,
) -> anyhow::Result<MutationOutcome> {
    // Returns Ok(true) if this driver set the marker, Ok(false) if the lease
    // ownership fence rejected the transaction (lease lost or marker already set
    // by a concurrent driver). We classify Ok(false) by reloading the row.
    let raw: anyhow::Result<bool> = match ctx.action {
        "ban" => {
            let target = ctx
                .target_pubkey
                .ok_or_else(|| anyhow::anyhow!("ban requires target_pubkey"))?;
            state
                .db
                .execute_ban_with_marker(
                    action_id,
                    lease_token,
                    ctx.community_id,
                    target,
                    ctx.actor_pubkey,
                    ctx.reason,
                )
                .await
                .map_err(|e| anyhow::anyhow!("ban failed: {e}"))
        }
        "timeout" => {
            let target = ctx
                .target_pubkey
                .ok_or_else(|| anyhow::anyhow!("timeout requires target_pubkey"))?;
            let until = ctx

View on GitHub (pinned to eed74bde2f)

Solutions

  1. Ensure the code path that enqueues the ban action always sets target_pubkey before the driver picks it up.
  2. Query the actions table for rows of type 'ban' with NULL target_pubkey and repair or discard them.
  3. Add a NOT NULL constraint or insert-time validation on the ban action's target_pubkey column.
  4. Verify the ActionCtx loader maps the correct DB column into ctx.target_pubkey.

Example fix

// before
actions::insert(Action { kind: "ban", community_id, reason, ..Default::default() })?;
// after
let target = reported_pubkey.ok_or_else(|| anyhow!("report has no target to ban"))?;
actions::insert(Action { kind: "ban", target_pubkey: Some(target), community_id, reason, ..Default::default() })?;
Defensive patterns

Strategy: validation

Validate before calling

pub fn enqueue_ban(action_id_target: [u8; 32], community_id: i64, reason: String) -> anyhow::Result<()> {
    anyhow::ensure!(!reason.is_empty(), "ban requires a reason");
    actions::insert(Action {
      kind: "ban",
      target_pubkey: Some(action_id_target),
      community_id,
      reason,
      ..Default::default()
    })?;
    Ok(())
}

Type guard

fn ban_target(ctx: &ActionCtx) -> Option<&[u8; 32]> {
    ctx.target_pubkey.as_ref().and_then(|b| b.try_into().ok())
}

Try / catch

match run_atomic_mutation(&state, ctx).await {
  Err(e) if e.to_string().contains("ban requires target_pubkey") => {
    tracing::error!(action_id = %action_id, "malformed ban action: dropping");
    mark_action_failed(action_id, "missing target_pubkey").await?;
  }
  Err(e) => return Err(e),
  Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: An enforcement action row of type 'ban' was created (or loaded into `ActionCtx`) without its `target_pubkey` populated — e.g. the action was enqueued from a report decision that omitted the target, or the DB column was NULL when the driver leased the action.

Common situations: A report-resolution flow writing a ban action without resolving the reported user's pubkey; manual DB edits or migrations that inserted action rows with NULL target_pubkey; a schema/type mismatch where the target was stored in a different column than the ctx loader reads.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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