block/buzz · error · anyhow::Error

cannot derive community host from RELAY_URL; pass --host or

Error message

cannot derive community host from RELAY_URL; pass --host or set a valid RELAY_URL

What it means

RELAY_URL WAS provided (non-empty after trim), but buzz_core::tenant::relay_url_authority() returned an empty authority for it, so resolve_submit_host() cannot derive a community host. The authority helper extracts host + explicit non-default port; it yields empty for values that are not parseable URLs with a usable host — no scheme/bad scheme, empty host, or a bare string the URL parser rejects. Distinct from error 33, which fires when RELAY_URL is missing entirely.

Source

Thrown at crates/buzz-deletion/src/lib.rs:520

fn resolve_submit_host(host: Option<&str>, relay_url: Option<&str>) -> Result<String> {
    if let Some(host) = host {
        let host = host.trim();
        if host.is_empty() {
            anyhow::bail!("--host must not be empty");
        }
        return Ok(host.to_owned());
    }

    let relay_url = relay_url
        .map(str::trim)
        .filter(|value| !value.is_empty())
        .ok_or_else(|| {
            anyhow::anyhow!("cannot derive community host; pass --host or set RELAY_URL")
        })?;
    let host = buzz_core::tenant::relay_url_authority(relay_url);
    if host.is_empty() {
        anyhow::bail!(
            "cannot derive community host from RELAY_URL; pass --host or set a valid RELAY_URL"
        );
    }
    Ok(host)
}

async fn connect_store() -> Result<DeletionStore> {
    let database_url = required_env("DATABASE_URL")?;
    let db = Db::new(&DbConfig {
        database_url,
        max_connections: env_parse("BUZZ_DB_POOL_SIZE", 20),
        ..DbConfig::default()
    })
    .await?;
    Ok(store(&db))
}

fn resolve_s3_region(buzz_region: Option<String>, aws_region: Option<String>) -> String {

View on GitHub (pinned to f956e6fe06)

Solutions

  1. Set RELAY_URL as a full WebSocket URL including scheme: ws://localhost:3000 (dev) or wss://relay.example.com (prod).
  2. Or bypass derivation with an explicit `--host relay.example.com` (authority form: host, plus non-default port such as localhost:3000).
  3. Echo-check the value in the exact execution context (`echo "[$RELAY_URL]"`) to catch interpolation/templating that stripped the scheme.
  4. Keep the same URL clients use — the derived authority must match the host string the relay seeded at startup.

Example fix

# before
RELAY_URL=localhost:3000 buzz-deletion submit ...
# error: cannot derive community host from RELAY_URL; ...

# after
RELAY_URL=ws://localhost:3000 buzz-deletion submit ...
Defensive patterns

Strategy: validation

Validate before calling

# RELAY_URL must be a full ws(s) URL with a host, or derivation fails
url="${RELAY_URL:-}"
if ! [[ "$url" =~ ^wss?://[^/:]+ ]]; then
  echo "RELAY_URL must look like ws://host:port or wss://host — got: '$url'" >&2; exit 1
fi

Type guard

function isRelayUrl(v: string): boolean {
  return /^wss?:\/\/[a-zA-Z0-9.\[\]-]+(:\d+)?/.test(v);
}

Prevention

When it happens

Trigger: RELAY_URL="localhost:3000" (no ws:// scheme), RELAY_URL="buzz-relay" (bare word), RELAY_URL="ws://" (no host), or a URL with only an opaque path. Each parses without a host, so relay_url_authority returns "" and this error fires.

Common situations: Operators shortening the env var to host:port assuming scheme doesn't matter; docker-compose values interpolated to empty; RELAY_URL confused with DATABASE_URL host formats; YAML env entries losing the scheme through templating.

Related errors


AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16). Data as JSON: /api/errors/86c0650ae79dca06. Report an issue: GitHub.