block/buzz · error · anyhow::Error
RELAY_URL host ' ' is not mapped to a community. buzz-admin…
Error message
RELAY_URL host '{host}' is not mapped to a community.
buzz-admin operates on the configured relay's community; ensure the relay has started and seeded its community (or set RELAY_URL to a mapped host). What it means
Every buzz-admin operation is scoped to one community. resolve_admin_tenant derives an authority from RELAY_URL via relay_url_authority (host plus explicit non-default port, IPv6 brackets kept) and looks it up in the communities table. No row for that exact authority — which the relay seeds at startup — yields this error. Because the port matters, RELAY_URL=ws://localhost:3000 resolves 'localhost:3000', not 'localhost'.
Solutions
- Start the relay once against the same DATABASE_URL (just relay) so it seeds its community, then retry.
- Check what is seeded: SELECT id, host FROM communities; and align RELAY_URL so its authority matches a row exactly (include the port, e.g. ws://localhost:3000).
- Confirm DATABASE_URL for the CLI session points at the same database the relay uses.
- If the host is genuinely new, let the relay seed it rather than inserting a row by hand.
Example fix
# before export RELAY_URL=ws://localhost # authority 'localhost' != seeded 'localhost:3000' # after export RELAY_URL=ws://localhost:3000 # authority matches the row the relay seeded
Defensive patterns
Strategy: validation
Validate before calling
-- verify the mapping exists before running any buzz-admin command SELECT id, host FROM communities WHERE host = 'localhost:3000'; -- = relay_url_authority(RELAY_URL) -- no row => start the relay once, or fix RELAY_URL (host AND explicit non-default port)
Prevention
- Run `just relay` (or the relay container) once against the same DATABASE_URL before any admin command.
- Always set RELAY_URL with the full authority — port included — matching the relay's seeded host.
- In scripts, assert the lookup first: one SQL query prevents a class of wrong-community admin operations.
When it happens
Trigger: Running buzz-admin against a database the relay has never started on (communities table empty for that host); RELAY_URL pointing at a different relay/DB than the one seeded; omitting a non-default port so the derived authority differs from the seeded one; running against a freshly restored DB dump.
Common situations: Fresh dev environment where `just relay` was never run; staging vs prod URL confusion; RELAY_URL spelled without the port the relay actually seeded.
Related errors
- cannot derive community host; pass --host or set RELAY_URL
- channel not found in community
- BUZZ_RELAY_PRIVATE_KEY is required for…
- cannot derive community host from RELAY_URL; pass --host or…
- --channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY
AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20).
Data as JSON: /api/errors/8a653faddcc82ffe.
Report an issue: GitHub.
Appendix: source
Thrown at crates/buzz-admin/src/main.rs:612
/// `buzz-admin` runs inside the relay container (`compose exec relay
/// buzz-admin …`), so it shares the relay's `RELAY_URL` and resolves the same
/// single community against the durable `communities` host map. This is
/// deliberately NOT a default tenant: an unmapped host fails closed with an
/// error, mirroring the relay's own `bind_community` row-zero seam. The CLI is
/// single-community per invocation — there is no cross-community sweep.
async fn resolve_admin_tenant(db: &Db) -> Result<TenantContext> {
let relay_url =
std::env::var("RELAY_URL").unwrap_or_else(|_| "ws://localhost:3000".to_string());
// Derive the authority the *same* way startup seeding and live request
// resolution do (`buzz_core::tenant::relay_url_authority`): host plus an
// explicit non-default port, IPv6 brackets preserved. A plain
// `Url::host_str()` drops the port/brackets, so for `ws://localhost:3000`
// the admin would look up `localhost` while startup seeded `localhost:3000`
// — and `wss://relay.example:8443` would resolve `relay.example`. Sharing
// the helper keeps buzz-admin byte-identical to the community startup seeds.
let host = relay_url_authority(&relay_url);
let record = db.lookup_community_by_host(&host).await?.ok_or_else(|| {
anyhow::anyhow!(
"RELAY_URL host '{host}' is not mapped to a community.\n\
buzz-admin operates on the configured relay's community; ensure the \
relay has started and seeded its community (or set RELAY_URL to a \
mapped host)."
)
})?;
Ok(TenantContext::resolved(record.id, record.host))
}
async fn reconcile_channels(
channel_arg: Option<String>,
relay_key_arg: Option<String>,
) -> Result<()> {
use buzz_core::kind::KIND_NIP29_GROUP_ADMINS;
use buzz_db::event::EventQuery;
let db = connect_db().await?;
View on GitHub (pinned to ef2aa1ae38)