{"record":{"id":"0e806916c837fdbe","repo":"block/buzz","slug":"channel-requires-relay-key-or-buzz-relay-priva","errorCode":null,"errorMessage":"--channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY","messagePattern":"--channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":637,"sourceCode":"    Ok(TenantContext::resolved(record.id, record.host))\n}\n\nasync fn reconcile_channels(\n    channel_arg: Option<String>,\n    relay_key_arg: Option<String>,\n) -> Result<()> {\n    use buzz_core::kind::KIND_NIP29_GROUP_ADMINS;\n    use buzz_db::event::EventQuery;\n\n    let db = connect_db().await?;\n\n    // Resolve relay signing key: arg > env > ephemeral. Force-republish must\n    // never use an ephemeral key because it replaces an existing authoritative\n    // snapshot.\n    let configured_relay_key =\n        relay_key_arg.or_else(|| std::env::var(\"BUZZ_RELAY_PRIVATE_KEY\").ok());\n    if channel_arg.is_some() && configured_relay_key.is_none() {\n        return Err(anyhow::anyhow!(\n            \"--channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY\"\n        ));\n    }\n    let relay_keys = match configured_relay_key {\n        Some(key_hex) => {\n            Keys::parse(&key_hex).map_err(|e| anyhow::anyhow!(\"invalid relay key: {e}\"))?\n        }\n        None => {\n            let k = Keys::generate();\n            eprintln!(\n                \"Warning: no relay key provided — using ephemeral key {}\",\n                k.public_key().to_hex()\n            );\n            eprintln!(\"Events signed with this key won't be verifiable after this run.\");\n            eprintln!(\"Pass --relay-key or set BUZZ_RELAY_PRIVATE_KEY for production use.\");\n            k\n        }\n    };","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/block/buzz/blob/ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be/crates/buzz-admin/src/main.rs#L619-L655","documentation":"reconcile-channels republishes authoritative channel events. Without --channel it may fall back to an ephemeral key (with warnings) because it only bootstraps missing snapshots, but with --channel it force-replaces an existing channel's events — signing those with a throwaway key would make them unverifiable. The CLI therefore refuses when --channel is given and neither --relay-key nor BUZZ_RELAY_PRIVATE_KEY supplies the stable signing key.","triggerScenarios":"Running `buzz-admin reconcile-channels --channel <uuid>` with no --relay-key flag and no BUZZ_RELAY_PRIVATE_KEY in the environment.","commonSituations":"Operators copying the documented bootstrap command (no key) and adding --channel; CI jobs that only set DATABASE_URL/RELAY_URL.","solutions":["Pass the relay's secret key explicitly: buzz-admin reconcile-channels --channel <uuid> --relay-key <64-hex-secret>.","Or export BUZZ_RELAY_PRIVATE_KEY with the same secret the relay signs with, then re-run.","If you only meant to backfill missing events, drop --channel and let the ephemeral-key warning path run (bootstrap only).","Verify the key parses beforehand (see the 'invalid relay key' guidance) to avoid a second failure."],"exampleFix":"# before\nbuzz-admin reconcile-channels --channel 6f1c...  # -> --channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY\n# after\nbuzz-admin reconcile-channels --channel 6f1c... --relay-key \"$BUZZ_RELAY_PRIVATE_KEY\"","handlingStrategy":"validation","validationCode":"# enforce the flag invariant before invoking the CLI\nif [ \"$1\" = \"--channel\" ] || [[ \" $* \" == *\" --channel \"* ]]; then\n  [ -n \"${RELAY_KEY:-}${BUZZ_RELAY_PRIVATE_KEY:-}\" ] || { echo 'channel reconcile needs a relay key' >&2; exit 3; }\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make --relay-key mandatory in your reconcile runbooks whenever --channel is used.","Treat the ephemeral-key warning as bootstrap-only; never silence it in automation.","Keep the relay secret available to the admin environment so force-republish never blocks mid-run."],"tags":["buzz-admin","cli-usage","reconcile-channels","signing-key"],"backgroundTag":"missing-required-flag","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"}