{"record":{"id":"0990bbe3849921e5","repo":"block/buzz","slug":"kick-requires-target-pubkey","errorCode":null,"errorMessage":"kick requires target_pubkey","messagePattern":"kick requires target_pubkey","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-relay/src/handlers/report_resolution.rs","lineNumber":725,"sourceCode":"                .ok_or_else(|| anyhow::anyhow!(\"timeout requires timeout_until\"))?;\n            state\n                .db\n                .execute_timeout_with_marker(\n                    action_id,\n                    lease_token,\n                    ctx.community_id,\n                    target,\n                    ctx.actor_pubkey,\n                    until,\n                    ctx.reason,\n                )\n                .await\n                .map_err(|e| anyhow::anyhow!(\"timeout failed: {e}\"))\n        }\n        \"kick\" => {\n            let target = ctx\n                .target_pubkey\n                .ok_or_else(|| anyhow::anyhow!(\"kick requires target_pubkey\"))?;\n            let ch = ctx\n                .channel_id\n                .ok_or_else(|| anyhow::anyhow!(\"kick requires channel_id\"))?;\n            match state\n                .db\n                .execute_kick_with_marker(\n                    action_id,\n                    lease_token,\n                    ctx.community_id,\n                    ch,\n                    target,\n                    ctx.actor_pubkey,\n                )\n                .await\n                .map_err(|e| anyhow::anyhow!(\"kick failed: {e}\"))?\n            {\n                buzz_db::relay_admin_actions::KickWithMarkerResult::Removed => Ok(true),\n                buzz_db::relay_admin_actions::KickWithMarkerResult::AlreadyMarked => Ok(false),","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/crates/buzz-relay/src/handlers/report_resolution.rs#L707-L743","documentation":"The 'kick' arm of `run_atomic_mutation` requires both `ctx.target_pubkey` and `ctx.channel_id` to be `Some`; this specific error fires when the target user is missing. A kick removes a specific user from a specific channel, so without a target the enforcement transaction aborts.","triggerScenarios":"A kick enforcement action row was enqueued or leased with `target_pubkey: None` — the producer omitted the user to kick, or the DB column was NULL when the driver loaded the context.","commonSituations":"Kick decision made from a report where the offender's pubkey was never captured; manually inserted kick rows during testing; ctx loader reading the wrong column; user record deletion cascading the target field to NULL.","solutions":["Ensure the kick action producer always records target_pubkey when enqueuing the action.","Locate 'kick' action rows with NULL target_pubkey and fix or discard them.","Add insert-time validation or a NOT NULL constraint on the kick target column.","Verify the ActionCtx loader maps the kick target from the correct DB column."],"exampleFix":"// before\nactions::insert(Action { kind: \"kick\", channel_id: Some(ch), .. })?;\n// after\nactions::insert(Action {\n  kind: \"kick\",\n  target_pubkey: Some(offender_pubkey),\n  channel_id: Some(ch),\n  ..\n})?;","handlingStrategy":"validation","validationCode":"pub fn enqueue_kick(target: [u8; 32], channel_id: uuid::Uuid, reason: String) -> anyhow::Result<()> {\n  actions::insert(Action {\n    kind: \"kick\",\n    target_pubkey: Some(target),\n    channel_id: Some(channel_id),\n    reason,\n    ..Default::default()\n  })?;\n  Ok(())\n}","typeGuard":"fn kick_target(ctx: &ActionCtx) -> Option<(&[u8; 32], uuid::Uuid)> {\n  let target = ctx.target_pubkey.as_ref().and_then(|b| b.try_into().ok())?;\n  Some((target, ctx.channel_id?))\n}","tryCatchPattern":"match run_atomic_mutation(&state, ctx).await {\n  Err(e) if e.to_string().contains(\"kick requires target_pubkey\") => {\n    tracing::error!(action_id = %action_id, \"malformed kick action: dropping\");\n    mark_action_failed(action_id, \"missing target_pubkey\").await?;\n  }\n  Err(e) => return Err(e),\n  Ok(v) => Ok(v),\n}","preventionTips":["Make target_pubkey and channel_id NOT NULL for kick action rows.","Validate the kick payload (target + channel) when the moderation decision is created.","Add an integration test driving the kick enforcement path.","Verify the ctx loader reads the kick target from the correct column after schema changes."],"tags":["moderation","backend","rust","missing-field","state-machine"],"backgroundTag":"missing-required-argument","analyzedSha":"eed74bde2f4797714335ac10c56c0b0244c1def4","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}