block/buzz · error
timeout requires target_pubkey
Error message
timeout requires target_pubkey
What it means
The 'timeout' arm of `run_atomic_mutation` requires `ctx.target_pubkey` to be `Some`. A timeout enforcement action without a target user cannot be executed, so the driver aborts the atomic transaction with this error, mirroring the equivalent ban-arm guard.
Source
Thrown at crates/buzz-relay/src/handlers/report_resolution.rs:704
.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
.timeout_until
.ok_or_else(|| anyhow::anyhow!("timeout requires timeout_until"))?;
state
.db
.execute_timeout_with_marker(
action_id,
lease_token,
ctx.community_id,
target,
ctx.actor_pubkey,
until,
ctx.reason,
)
.await
.map_err(|e| anyhow::anyhow!("timeout failed: {e}"))
}
"kick" => {View on GitHub (pinned to eed74bde2f)
Solutions
- Ensure the timeout action producer always sets target_pubkey when enqueuing the action.
- Find and fix any 'timeout' action rows with NULL target_pubkey in the actions table.
- Add insert-time validation or a NOT NULL constraint for timeout targets.
- Confirm the ActionCtx loader populates target_pubkey from the correct column.
Example fix
// before
actions::insert(Action { kind: "timeout", timeout_until: Some(until), .. })?;
// after
actions::insert(Action {
kind: "timeout",
target_pubkey: Some(reported_pubkey),
timeout_until: Some(until),
..
})?; Defensive patterns
Strategy: validation
Validate before calling
pub fn enqueue_timeout(target: [u8; 32], until: chrono::DateTime<chrono::Utc>, reason: String) -> anyhow::Result<()> {
anyhow::ensure!(until > chrono::Utc::now(), "timeout expiry must be in the future");
actions::insert(Action { kind: "timeout", target_pubkey: Some(target), timeout_until: Some(until), reason, ..Default::default() })?;
Ok(())
} Type guard
fn timeout_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("timeout requires target_pubkey") => {
tracing::error!(action_id = %action_id, "malformed timeout 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 timeout action rows.
- Validate the action payload when the moderation decision is made.
- Add an integration test covering the timeout enforcement path end to end.
When it happens
Trigger: A timeout action row was enqueued or loaded with `target_pubkey: None` — the producer of the action (report decision handler) failed to record which user to timeout, or the DB column is NULL when the driver leases the action.
Common situations: Timeout decided from a report whose target user record was deleted between decision and enforcement; manually inserted action rows during testing; schema mismatch where the ctx loader reads the wrong column for the timeout target.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ban 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/9e022a370bed51e1.
Report an issue: GitHub.