block/buzz · error

sign kind:39001: {e}

Error message

sign kind:39001: {e}

What it means

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).

Source

Thrown at crates/buzz-admin/src/main.rs:601

                    .map_err(|e| anyhow::anyhow!("sign kind:39000: {e}"))?;
                db.replace_addressable_event(tenant.community(), &event, Some(channel.id))
                    .await?;
            }

            // kind:39001 — admins
            {
                let mut tags: Vec<Tag> = vec![Tag::parse(["d", &channel_id_str])?];
                for m in members
                    .iter()
                    .filter(|m| m.role == "owner" || m.role == "admin")
                {
                    let pk = hex::encode(&m.pubkey);
                    tags.push(Tag::parse(["p", &pk, &m.role])?);
                }
                let event = EventBuilder::new(Kind::Custom(KIND_NIP29_GROUP_ADMINS as u16), "")
                    .tags(tags)
                    .sign_with_keys(&relay_keys)
                    .map_err(|e| anyhow::anyhow!("sign kind:39001: {e}"))?;
                db.replace_addressable_event(tenant.community(), &event, Some(channel.id))
                    .await?;
            }
        }

        // kind:39002 — members
        {
            let mut tags: Vec<Tag> = vec![Tag::parse(["d", &channel_id_str])?];
            for m in &members {
                let pk = hex::encode(&m.pubkey);
                tags.push(Tag::parse(["p", &pk, "", &m.role])?);
            }
            let event = EventBuilder::new(Kind::Custom(39002), "")
                .tags(tags)
                .sign_with_keys(&relay_keys)
                .map_err(|e| anyhow::anyhow!("sign kind:39002: {e}"))?;
            db.replace_addressable_event(tenant.community(), &event, Some(channel.id))
                .await?;

View on GitHub (pinned to f956e6fe06)

Solutions

  1. Retry once to distinguish transient vs deterministic.
  2. 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`).
  3. If a custom/patched nostr crate is in use, revert to the workspace-pinned version and retest.
  4. 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.
Defensive patterns

Strategy: validation

Validate before calling

# same pre-verify: signing can only fail on key/dependency anomalies
python3 -c "import sys; bytes.fromhex(sys.argv[1])" "$BUZZ_RELAY_PRIVATE_KEY" \
  || { echo 'relay key is not valid hex' >&2; exit 1; }

Try / catch

if stderr.contains("sign kind:39001") { rerun once; if persistent, verify `cargo tree -i secp256k1` matches lockfile and report with full {e} }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16). Data as JSON: /api/errors/ffadcc64d869798b. Report an issue: GitHub.