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 = ctxView on GitHub (pinned to eed74bde2f)
Solutions
- Ensure the code path that enqueues the ban action always sets target_pubkey before the driver picks it up.
- Query the actions table for rows of type 'ban' with NULL target_pubkey and repair or discard them.
- Add a NOT NULL constraint or insert-time validation on the ban action's target_pubkey column.
- 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
- Make target_pubkey NOT NULL for ban/timeout/kick action rows.
- Validate actions at enqueue time, not at execution time.
- Add an integration test that drives every action kind through run_atomic_mutation.
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
- timeout requires target_pubkey
- kick requires target_pubkey
- timeout requires timeout_until
- ban failed: {e}
- timeout failed: {e}
AI-assisted analysis of block/buzz@eed74bde2f (2026-08-30).
Data as JSON: /api/errors/d37835dc76939451.
Report an issue: GitHub.