{"record":{"id":"ffadcc64d869798b","repo":"block/buzz","slug":"sign-kind-39001-e","errorCode":null,"errorMessage":"sign kind:39001: {e}","messagePattern":"sign kind:39001: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":601,"sourceCode":"                    .map_err(|e| anyhow::anyhow!(\"sign kind:39000: {e}\"))?;\n                db.replace_addressable_event(tenant.community(), &event, Some(channel.id))\n                    .await?;\n            }\n\n            // kind:39001 — admins\n            {\n                let mut tags: Vec<Tag> = vec![Tag::parse([\"d\", &channel_id_str])?];\n                for m in members\n                    .iter()\n                    .filter(|m| m.role == \"owner\" || m.role == \"admin\")\n                {\n                    let pk = hex::encode(&m.pubkey);\n                    tags.push(Tag::parse([\"p\", &pk, &m.role])?);\n                }\n                let event = EventBuilder::new(Kind::Custom(KIND_NIP29_GROUP_ADMINS as u16), \"\")\n                    .tags(tags)\n                    .sign_with_keys(&relay_keys)\n                    .map_err(|e| anyhow::anyhow!(\"sign kind:39001: {e}\"))?;\n                db.replace_addressable_event(tenant.community(), &event, Some(channel.id))\n                    .await?;\n            }\n        }\n\n        // kind:39002 — members\n        {\n            let mut tags: Vec<Tag> = vec![Tag::parse([\"d\", &channel_id_str])?];\n            for m in &members {\n                let pk = hex::encode(&m.pubkey);\n                tags.push(Tag::parse([\"p\", &pk, \"\", &m.role])?);\n            }\n            let event = EventBuilder::new(Kind::Custom(39002), \"\")\n                .tags(tags)\n                .sign_with_keys(&relay_keys)\n                .map_err(|e| anyhow::anyhow!(\"sign kind:39002: {e}\"))?;\n            db.replace_addressable_event(tenant.community(), &event, Some(channel.id))\n                .await?;","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/block/buzz/blob/f956e6fe06a76e50cbd8fba1a162482e752e7f1a/crates/buzz-admin/src/main.rs#L583-L619","documentation":"While republishing a channel's kind:39001 (NIP-29 group admins, KIND_NIP29_GROUP_ADMINS) snapshot — the d-tagged addressable event listing owner/admin pubkeys as p-tags with their roles — EventBuilder::sign_with_keys(&relay_keys) failed and reconcile_channels wrapped it. Same class as the kind:39000/39002 sign errors: the key already parsed, so a failure is an unexpected secp256k1/nostr-internal condition, not bad channel data (tag construction errors are reported separately).","triggerScenarios":"Deterministic or transient secp256k1 signing failures from the nostr crate during reconcile-channels with a valid relay key; realistically only seen with dependency version skew (nostr vs secp256k1) or a miscompiled crypto backend after toolchain changes.","commonSituations":"Post `cargo update` builds; locally patched nostr versions; cross-compiled binaries with a broken secp256k1 backend. Channel/admin data itself cannot trigger this specific message.","solutions":["Retry once to distinguish transient vs deterministic.","Inspect the {e} text, then verify dependency coherence: `cargo tree -p buzz-admin -i secp256k1` and rebuild from the committed Cargo.lock (`git checkout Cargo.lock && cargo build`).","If a custom/patched nostr crate is in use, revert to the workspace-pinned version and retest.","Persisting failure with pinned deps: preserve the exact command, key fingerprint, and {e} for a bug report — this code path assumes signing cannot fail for parsed keys."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# same pre-verify: signing can only fail on key/dependency anomalies\npython3 -c \"import sys; bytes.fromhex(sys.argv[1])\" \"$BUZZ_RELAY_PRIVATE_KEY\" \\\n  || { echo 'relay key is not valid hex' >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"if stderr.contains(\"sign kind:39001\") { rerun once; if persistent, verify `cargo tree -i secp256k1` matches lockfile and report with full {e} }","preventionTips":["Pin crypto deps via Cargo.lock in CI builds for any binary that signs Nostr events.","Keep a scratch command that signs any event with the same key to bisect key vs environment."],"tags":["buzz-admin","nostr","event-signing","secp256k1","kind-39001"],"backgroundTag":"event-signing-failed","analyzedSha":"f956e6fe06a76e50cbd8fba1a162482e752e7f1a","analyzedAt":"2026-08-16T22:11:40.750Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}