block/buzz · error

delete requires target_event_id

Error message

delete requires target_event_id

What it means

`run_atomic_mutation` was asked to execute a "delete" enforcement action, but `EnforcementCtx.target_event_id` was `None`. Deleting a reported event requires its id; the handler cannot proceed. Like the kick/timeout variants, this is an internal invariant failure indicating the enforcement-context builder failed to decode or attach the report's event target.

Source

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

                    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,
                    lease_token,
                    ctx.community_id,
                    target,
                    parent_id.as_deref(),
                    root_id.as_deref(),
                )
                .await

View on GitHub (pinned to eed74bde2f)

Solutions

  1. Verify the resolution action matches the report's target kind: only resolve event-kind reports (target decode yields an event id) with "delete".
  2. Check the report row's stored target (kind + hex) — re-trigger resolution after fixing the target, or resolve with "ban"/"kick" instead.
  3. If building contexts in code/tests, populate `target_event_id` from the decoded report target before calling `drive_enforcement`.
  4. Add early validation in the resolve endpoint that rejects delete-on-pubkey reports with a client-facing error rather than this internal one.

Example fix

// before
let ctx = EnforcementCtx { action: "delete", target_event_id: None, ..base };
// after
let target_event_id = report.target_event_id
    .ok_or_else(|| anyhow::anyhow!("cannot delete: report target is not an event"))?;
let ctx = EnforcementCtx { action: "delete", target_event_id: Some(target_event_id), ..base };
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_delete_ctx(ctx: &EnforcementCtx) -> anyhow::Result<&EnforcementCtx<'_>> {
    anyhow::ensure!(ctx.action != "delete" || ctx.target_event_id.is_some(),
        "delete enforcement requires target_event_id; report target must be an event");
    Ok(ctx)
}
// call before drive_enforcement:
// ensure_delete_ctx(&ctx)?;

Type guard

fn delete_ctx_is_complete(ctx: &EnforcementCtx<'_>) -> bool {
    ctx.action != "delete" || ctx.target_event_id.is_some()
}

Try / catch

match run_atomic_mutation(state, action_id, lease_token, &ctx).await {
    Err(e) if e.to_string().contains("delete requires target_event_id") => {
        mark_action_failed(action_id, "report target is not an event; delete impossible".into());
    }
    other => other?,
}

Prevention

When it happens

Trigger: 1) The report targeted a pubkey (user-level report) but was resolved with a "delete" action instead. 2) The report target hex failed to decode to a valid event id upstream and was left as `None`. 3) A custom or hand-rolled `EnforcementCtx` for delete omitted `target_event_id`. 4) Legacy admin-action rows whose stored report target predates event-id scoping.

Common situations: Operator UIs letting admins pick "delete" on a user-level report; corrupt or partially-written report target columns; forks or scripts inserting recovery actions with the wrong target kind; report kind registry changes leaving old rows un-decodable.

Related errors


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