{"record":{"id":"720b57a88b49671a","repo":"block/buzz","slug":"unsupported-project-announcement-kind","errorCode":null,"errorMessage":"unsupported project announcement kind","messagePattern":"unsupported project announcement kind","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-acp/src/lib.rs","lineNumber":1716,"sourceCode":"            observer.as_ref(),\n            &control.request_id,\n            \"ok\",\n            &published_events,\n            None,\n        );\n    });\n}\n\nfn build_project_owner_announcement_events(\n    announcements: Vec<ProjectOwnerAnnouncementTemplate>,\n    keys: &nostr::Keys,\n) -> Result<Vec<nostr::Event>> {\n    let now = nostr::Timestamp::now().as_secs();\n    announcements\n        .into_iter()\n        .map(|template| {\n            if !matches!(template.kind, 30_617 | 30_621) {\n                anyhow::bail!(\"unsupported project announcement kind\");\n            }\n            if !template.tags.iter().any(|tag| {\n                tag.first().is_some_and(|value| value == \"d\")\n                    && tag.get(1).is_some_and(|value| !value.trim().is_empty())\n            }) {\n                anyhow::bail!(\"project announcement is missing its address\");\n            }\n            let tags = template\n                .tags\n                .into_iter()\n                .map(|tag| {\n                    nostr::Tag::parse(tag)\n                        .map_err(|error| anyhow::anyhow!(\"invalid project tag: {error}\"))\n                })\n                .collect::<Result<Vec<_>>>()?;\n            let created_at = template.created_at.unwrap_or(now);\n            if created_at > now.saturating_add(300) {\n                anyhow::bail!(\"project announcement timestamp is too far in the future\");","sourceCodeStart":1698,"sourceCodeEnd":1734,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-acp/src/lib.rs#L1698-L1734","documentation":"build_project_owner_announcement_events only signs project-owner announcement templates whose kind is 30617 (NIP-34 git repository announcement) or 30621 (project announcement). Any other kind is rejected with this bail because the relay has no handler that will accept or process such an announcement.","triggerScenarios":"Agent/harness startup configuration contains a project_owner_announcements template entry whose kind is any value other than 30617 or 30621 (e.g. a copied 30078 chat kind or a made-up kind), and startup reaches build_project_owner_announcement_events.","commonSituations":"Hand-edited harness config or a template copied from a different event type; a buzz-acp version change that narrowed the allowed kinds while stale config is still deployed.","solutions":["Set the template's kind to 30617 (repo announcement) or 30621 (project announcement)","Cross-check the canonical kind registry in crates/buzz-core/src/kind.rs before inventing kind values","Regenerate the config from a current example config instead of hand-editing"],"exampleFix":"# agent config\n# before\nproject_owner_announcements:\n  - kind: 30078\n    tags: [[\"d\", \"my-project\"]]\n# after\nproject_owner_announcements:\n  - kind: 30621\n    tags: [[\"d\", \"my-project\"]]","handlingStrategy":"validation","validationCode":"// Preflight templates before harness startup\nconst SUPPORTED: &[u16] = &[30617, 30621];\nfor t in &config.project_owner_announcements {\n    if !SUPPORTED.contains(&t.kind) {\n        anyhow::bail!(\"template kind {} not in {SUPPORTED:?}\", t.kind);\n    }\n}","typeGuard":"fn is_supported_announcement_kind(kind: u16) -> bool {\n    matches!(kind, 30617 | 30621)\n}","tryCatchPattern":null,"preventionTips":["Treat buzz-core/src/kind.rs as the single source of kind integers; never hand-pick kind values in config","Validate the whole startup config in one pass before spawning agents so failures surface early with full context"],"tags":["config","nostr","validation","event-kind","buzz-acp"],"backgroundTag":"unsupported-event-kind","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}