{"record":{"id":"9e022a370bed51e1","repo":"block/buzz","slug":"timeout-requires-target-pubkey","errorCode":null,"errorMessage":"timeout requires target_pubkey","messagePattern":"timeout requires target_pubkey","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-relay/src/handlers/report_resolution.rs","lineNumber":704,"sourceCode":"                .target_pubkey\n                .ok_or_else(|| anyhow::anyhow!(\"ban requires target_pubkey\"))?;\n            state\n                .db\n                .execute_ban_with_marker(\n                    action_id,\n                    lease_token,\n                    ctx.community_id,\n                    target,\n                    ctx.actor_pubkey,\n                    ctx.reason,\n                )\n                .await\n                .map_err(|e| anyhow::anyhow!(\"ban failed: {e}\"))\n        }\n        \"timeout\" => {\n            let target = ctx\n                .target_pubkey\n                .ok_or_else(|| anyhow::anyhow!(\"timeout requires target_pubkey\"))?;\n            let until = ctx\n                .timeout_until\n                .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\" => {","sourceCodeStart":686,"sourceCodeEnd":722,"githubUrl":"https://github.com/block/buzz/blob/eed74bde2f4797714335ac10c56c0b0244c1def4/crates/buzz-relay/src/handlers/report_resolution.rs#L686-L722","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nactions::insert(Action { kind: \"timeout\", timeout_until: Some(until), .. })?;\n// after\nactions::insert(Action {\n  kind: \"timeout\",\n  target_pubkey: Some(reported_pubkey),\n  timeout_until: Some(until),\n  ..\n})?;","handlingStrategy":"validation","validationCode":"pub fn enqueue_timeout(target: [u8; 32], until: chrono::DateTime<chrono::Utc>, reason: String) -> anyhow::Result<()> {\n  anyhow::ensure!(until > chrono::Utc::now(), \"timeout expiry must be in the future\");\n  actions::insert(Action { kind: \"timeout\", target_pubkey: Some(target), timeout_until: Some(until), reason, ..Default::default() })?;\n  Ok(())\n}","typeGuard":"fn timeout_target(ctx: &ActionCtx) -> Option<&[u8; 32]> {\n    ctx.target_pubkey.as_ref().and_then(|b| b.try_into().ok())\n}","tryCatchPattern":"match run_atomic_mutation(&state, ctx).await {\n  Err(e) if e.to_string().contains(\"timeout requires target_pubkey\") => {\n    tracing::error!(action_id = %action_id, \"malformed timeout 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 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."],"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"}