{"record":{"id":"55010c8bee26573f","repo":"block/buzz","slug":"missing-e-tag-for-target-event","errorCode":null,"errorMessage":"missing e tag for target event","messagePattern":"missing e tag for target event","errorType":"validation","errorClass":"IngestError::Rejected","httpStatus":400,"severity":"error","filePath":"crates/buzz-relay/src/handlers/side_effects.rs","lineNumber":648,"sourceCode":"        9005 => {\n            // DELETE_EVENT: event author OR channel owner/admin.\n            if let Some(action_id) = extract_tag_value(event, \"action_id\") {\n                Uuid::parse_str(&action_id)\n                    .map_err(|_| anyhow::anyhow!(\"invalid action_id tag\"))?;\n            }\n\n            // Extract target event from e tag to check authorship.\n            let target_id = event\n                .tags\n                .iter()\n                .find_map(|tag| {\n                    if tag.kind().to_string() == \"e\" {\n                        tag.content().and_then(|v| hex::decode(v).ok())\n                    } else {\n                        None\n                    }\n                })\n                .ok_or_else(|| anyhow::anyhow!(\"missing e tag for target event\"))?;\n\n            // Verify the target event exists and belongs to the h-tag channel\n            // BEFORE storage. Fail closed: missing target → reject.\n            let target_event = state\n                .db\n                .get_event_by_id(tenant.community(), &target_id)\n                .await\n                .map_err(|e| anyhow::anyhow!(\"db error looking up target: {e}\"))?\n                .ok_or_else(|| anyhow::anyhow!(\"target event not found\"))?;\n\n            match target_event.channel_id {\n                Some(target_ch) if target_ch != channel_id => {\n                    return Err(anyhow::anyhow!(\n                        \"target event belongs to a different channel\"\n                    ));\n                }\n                None => {\n                    return Err(anyhow::anyhow!(\"target event has no channel\"));","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/block/buzz/blob/f956e6fe06a76e50cbd8fba1a162482e752e7f1a/crates/buzz-relay/src/handlers/side_effects.rs#L630-L666","documentation":"Thrown by kind:9005 (DELETE_EVENT) when no e tag with a hex-decodable event id can be found. The extractor find_maps over tags for kind \"e\" whose content hex-decodes successfully — so both a missing e tag and an e tag whose value is not valid hex (wrong length, non-hex characters) produce this error.","triggerScenarios":"Publishing kind:9005 without an e tag at all, or with [[\"e\", \"not-a-hex-id\"], [\"e\", \"zzzz\"]] or an id with the 0x prefix. Only the first decodable e tag is used; an id that is a bech32 (note1...) encoding will also fail hex decoding.","commonSituations":"Passing a note1.../npub-style identifier where the relay expects 64-char hex; URL-decoding a deep link id incompletely; SDK field mix-ups sending the channel id in the e tag; truncation of the 64-char id by log/UI layers.","solutions":["Include [\"e\", <64-char lowercase hex event id>] of the message you want deleted.","Convert note1... identifiers to hex before publishing (bech32 decode).","Verify the id length is exactly 64 hex characters with no 0x prefix or whitespace.","Confirm you are deleting a message id, not a channel uuid or a user pubkey."],"exampleFix":"// before — bech32 id or missing e tag\n{ kind: 9005, tags: [[\"h\", ch], [\"action_id\", uuid]] }              // no e tag\n{ kind: 9005, tags: [[\"h\", ch], [\"e\", \"note1qyq...\"]] }          // not hex\n\n// after\n{ kind: 9005, tags: [[\"h\", ch], [\"e\", hexEventId]] } // hexEventId = 64 hex chars","handlingStrategy":"validation","validationCode":"const HEX64_RE = /^[0-9a-f]{64}$/;\n\nfunction targetTag(eventId: string): string[] {\n  const hex = eventId.startsWith(\"note1\") ? bech32ToHex(eventId) : eventId;\n  if (!HEX64_RE.test(hex)) throw new Error(\"Target event id must be 64 hex chars (convert note1... ids first)\");\n  return [\"e\", hex];\n}","typeGuard":"function isHexEventId(v: string): boolean {\n  return /^[0-9a-fA-F]{64}$/.test(v.trim());\n}","tryCatchPattern":"try {\n  await sdk.publish(deleteEvent);\n} catch (e) {\n  if (String(e).includes(\"missing e tag for target event\")) {\n    throw new Error(\"No valid [\\\"e\\\", <64-char hex id\\\"] tag on the delete event\");\n  } else throw e;\n}","preventionTips":["Convert bech32 note1... ids to hex before building the e tag.","Never put a channel uuid, npub, or a truncated id in the e tag.","Assert the id is exactly 64 hex characters in your event builder."],"tags":["nostr","validation","kind-9005","missing-tag","event-id-format","relay"],"backgroundTag":"missing-required-tag","analyzedSha":"f956e6fe06a76e50cbd8fba1a162482e752e7f1a","analyzedAt":"2026-08-16T22:11:40.750Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}