block/buzz · error · anyhow::Error

BUZZ_RELAY_PRIVATE_KEY is required for…

Error message

BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member.
The relay must have a stable signing key to publish kind:13534 events.

What it means

add-member and remove-member republish the relay-signed kind:13534 membership list, so connect_member_services requires the relay's stable signing key from BUZZ_RELAY_PRIVATE_KEY. If the variable is absent from the environment, the CLI aborts before touching the DB or Redis. This is a deliberate guard: an ephemeral key would make the published roster unverifiable against the relay's identity.

Solutions

  1. Export the same secret the relay uses: export BUZZ_RELAY_PRIVATE_KEY=<relay-secret-hex-or-nsec> (check the relay service's env).
  2. Or run one-shot: BUZZ_RELAY_PRIVATE_KEY=... buzz-admin add-member --pubkey <hex> --role member.
  3. Persist it in the shell profile or the admin job's environment (.env next to where you invoke buzz-admin).
  4. Verify with: test -n "$BUZZ_RELAY_PRIVATE_KEY" && echo set.

Example fix

# before
buzz-admin add-member --pubkey <hex> --role member  # -> BUZZ_RELAY_PRIVATE_KEY is required
# after
export BUZZ_RELAY_PRIVATE_KEY="$(grep -E '^BUZZ_RELAY_PRIVATE_KEY=' /path/to/.env | cut -d= -f2-)"
buzz-admin add-member --pubkey <hex> --role member
Defensive patterns

Strategy: validation

Validate before calling

# guard in the operator shell / CI before invoking buzz-admin
if [ -z "$BUZZ_RELAY_PRIVATE_KEY" ]; then
  echo "BUZZ_RELAY_PRIVATE_KEY missing — refusing to run member commands" >&2
  exit 3
fi

Prevention

When it happens

Trigger: Running `buzz-admin add-member`/`remove-member` in a shell that has not sourced .env; running the CLI from cron/CI where only the relay container has the variable; typo'd variable name (BUZZ_RELAY_PRIVATEKEY, RELAY_PRIVATE_KEY).

Common situations: Operator shells that never sourced the project .env copied from .env.example; deployments where the key is injected only into the relay service, not the admin job.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20). Data as JSON: /api/errors/41d530b34cd9be4c. Report an issue: GitHub.

Appendix: source

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

    }

    tracing::info!(
        member_count = members.len(),
        ts,
        "NIP-43 membership list published by buzz-admin"
    );
    Ok(())
}

/// Connect to DB, Redis pub/sub, and load the relay keypair.
///
/// `BUZZ_RELAY_PRIVATE_KEY` is required — the CLI signs kind:13534 events.
async fn connect_member_services() -> Result<(Db, Arc<PubSubManager>, Keys)> {
    let db = connect_db().await?;

    let relay_keypair = {
        let hex = std::env::var("BUZZ_RELAY_PRIVATE_KEY").map_err(|_| {
            anyhow::anyhow!(
                "BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member.\n\
                 The relay must have a stable signing key to publish kind:13534 events."
            )
        })?;
        Keys::parse(&hex).map_err(|e| anyhow::anyhow!("invalid BUZZ_RELAY_PRIVATE_KEY: {e}"))?
    };

    let redis_url =
        std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://localhost:6379".to_string());

    let redis_pool = {
        let cfg = deadpool_redis::Config::from_url(&redis_url);
        cfg.create_pool(Some(deadpool_redis::Runtime::Tokio1))
            .map_err(|e| anyhow::anyhow!("Redis pool creation failed: {e}"))?
    };

    let pubsub = Arc::new(
        PubSubManager::new(&redis_url, redis_pool)

View on GitHub (pinned to ef2aa1ae38)