{"record":{"id":"41d530b34cd9be4c","repo":"block/buzz","slug":"buzz-relay-private-key-is-required-for-add-member","errorCode":null,"errorMessage":"BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member.\nThe relay must have a stable signing key to publish kind:13534 events.","messagePattern":"BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member\\.\nThe relay must have a stable signing key to publish kind:13534 events\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":552,"sourceCode":"    }\n\n    tracing::info!(\n        member_count = members.len(),\n        ts,\n        \"NIP-43 membership list published by buzz-admin\"\n    );\n    Ok(())\n}\n\n/// Connect to DB, Redis pub/sub, and load the relay keypair.\n///\n/// `BUZZ_RELAY_PRIVATE_KEY` is required — the CLI signs kind:13534 events.\nasync fn connect_member_services() -> Result<(Db, Arc<PubSubManager>, Keys)> {\n    let db = connect_db().await?;\n\n    let relay_keypair = {\n        let hex = std::env::var(\"BUZZ_RELAY_PRIVATE_KEY\").map_err(|_| {\n            anyhow::anyhow!(\n                \"BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member.\\n\\\n                 The relay must have a stable signing key to publish kind:13534 events.\"\n            )\n        })?;\n        Keys::parse(&hex).map_err(|e| anyhow::anyhow!(\"invalid BUZZ_RELAY_PRIVATE_KEY: {e}\"))?\n    };\n\n    let redis_url =\n        std::env::var(\"REDIS_URL\").unwrap_or_else(|_| \"redis://localhost:6379\".to_string());\n\n    let redis_pool = {\n        let cfg = deadpool_redis::Config::from_url(&redis_url);\n        cfg.create_pool(Some(deadpool_redis::Runtime::Tokio1))\n            .map_err(|e| anyhow::anyhow!(\"Redis pool creation failed: {e}\"))?\n    };\n\n    let pubsub = Arc::new(\n        PubSubManager::new(&redis_url, redis_pool)","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/block/buzz/blob/ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be/crates/buzz-admin/src/main.rs#L534-L570","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Export the same secret the relay uses: export BUZZ_RELAY_PRIVATE_KEY=<relay-secret-hex-or-nsec> (check the relay service's env).","Or run one-shot: BUZZ_RELAY_PRIVATE_KEY=... buzz-admin add-member --pubkey <hex> --role member.","Persist it in the shell profile or the admin job's environment (.env next to where you invoke buzz-admin).","Verify with: test -n \"$BUZZ_RELAY_PRIVATE_KEY\" && echo set."],"exampleFix":"# before\nbuzz-admin add-member --pubkey <hex> --role member  # -> BUZZ_RELAY_PRIVATE_KEY is required\n# after\nexport BUZZ_RELAY_PRIVATE_KEY=\"$(grep -E '^BUZZ_RELAY_PRIVATE_KEY=' /path/to/.env | cut -d= -f2-)\"\nbuzz-admin add-member --pubkey <hex> --role member","handlingStrategy":"validation","validationCode":"# guard in the operator shell / CI before invoking buzz-admin\nif [ -z \"$BUZZ_RELAY_PRIVATE_KEY\" ]; then\n  echo \"BUZZ_RELAY_PRIVATE_KEY missing — refusing to run member commands\" >&2\n  exit 3\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Source the project .env in every shell and CI job that runs buzz-admin.","Keep the admin job's env template next to .env.example and diff them on deploy.","Name the requirement in runbooks: member commands need the relay's signing key, not just DATABASE_URL."],"tags":["buzz-admin","env-var","configuration","membership"],"backgroundTag":"missing-env-var","analyzedSha":"ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}