block/buzz · error
RELAY_URL host '{host}' is not mapped to a community. buzz-a
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
resolve_admin_tenant() derives the authority from RELAY_URL (default ws://localhost:3000) using buzz_core::tenant::relay_url_authority — host plus explicit non-default port, IPv6 brackets preserved — and then looks that host up in the communities table via lookup_community_by_host. The error means no community row matches that authority: the relay has never started (startup seeding creates the mapping), it seeded under a different host string, or RELAY_URL points somewhere else. The shared helper guarantees the admin CLI derives the key byte-identically to how the relay seeded it (e.g. localhost:3000, not localhost).
Source
Thrown at crates/buzz-admin/src/main.rs:464
/// `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 f956e6fe06)
Solutions
- Start the relay once against the same DATABASE_URL (`just relay`) so startup seeding inserts the community row for its host, then re-run buzz-admin.
- Set RELAY_URL to the exact public URL clients use for that relay (host AND port), so relay_url_authority produces the same string that was seeded — e.g. wss://relay.example.com, not the internal host:port if seeding happened at the edge.
- Verify the mapping directly in Postgres: `SELECT id, host FROM communities;` and compare the host value character-by-character with the authority you expect from RELAY_URL.
- Confirm DATABASE_URL points at the same database the relay writes to — a mismatched DB looks exactly like an unmapped host.
Example fix
# before: relay never started on this DB RELAY_URL=ws://localhost:3000 buzz-admin ... # error: RELAY_URL host 'localhost:3000' is not mapped to a community. # after: seed first, then administer just relay & # startup seeding maps localhost:3000 -> community RELAY_URL=ws://localhost:3000 buzz-admin ...
Defensive patterns
Strategy: validation
Validate before calling
-- Verify the community mapping exists before running buzz-admin: SELECT host FROM communities WHERE host = 'localhost:3000'; -- must return the row your RELAY_URL derives to
Prevention
- Always start the relay once against a fresh database before running admin commands.
- Use the exact public URL for RELAY_URL that clients use — authority derivation includes non-default ports.
- Keep DATABASE_URL for admin jobs identical to the relay's; a different DB mimics an unmapped host.
When it happens
Trigger: Running buzz-admin against a fresh database where `just relay` has never run; setting RELAY_URL=ws://localhost:3000 while the relay was seeded behind a proxy as relay.example.com (or vice versa); changing the relay's port so the authority string (host:port) no longer matches the seeded row; running the admin CLI against the wrong DATABASE_URL so it queries an empty/unrelated communities table.
Common situations: Dev database reset (docker volume wiped) without restarting the relay; staging relay seeded via a public hostname but the operator exports the internal hostname; port mismatch — relay reachable on 3000 but seeded under 443/default so the stored host lacks the :3000 suffix; multi-community database where the admin points at a host nobody seeded.
Related errors
- channel {target} not found in community {}
- BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-mem
- invalid BUZZ_RELAY_PRIVATE_KEY: {e}
- Redis pool creation failed: {e}
- PubSub init failed: {e}
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/8a653faddcc82ffe.
Report an issue: GitHub.