block/buzz · error · anyhow::Error

setup-mode relay connect error: {e}

Error message

setup-mode relay connect error: {e}

What it means

Setup mode's first relay interaction is HarnessRelay::connect — establish the WebSocket to BUZZ_RELAY_URL and complete the NIP-42 auth handshake with the harness key. This wrapped error means that connect failed, so setup mode exits before any subscription or watermark is attempted.

Source

Thrown at crates/buzz-acp/src/setup_mode.rs:333

    );

    let pubkey_hex = config.keys.public_key().to_hex();

    // Parse BUZZ_AUTH_TAG for relay membership / NIP-OA.
    let relay_auth_tag: Option<nostr::Tag> = std::env::var("BUZZ_AUTH_TAG")
        .ok()
        .filter(|s| !s.is_empty())
        .and_then(|s| buzz_sdk::nip_oa::parse_auth_tag(&s).ok());

    let startup_watermark: u64 = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap_or_default()
        .as_secs();

    let mut relay =
        HarnessRelay::connect(&config.relay_url, &config.keys, &pubkey_hex, relay_auth_tag)
            .await
            .map_err(|e| anyhow::anyhow!("setup-mode relay connect error: {e}"))?;

    if let Err(e) = relay.set_startup_watermark(startup_watermark).await {
        tracing::warn!("setup-mode: failed to set startup watermark: {e}");
    }

    relay
        .subscribe_membership_notifications()
        .await
        .map_err(|e| anyhow::anyhow!("setup-mode membership subscribe error: {e}"))?;

    tracing::info!("setup-mode: connected and subscribed to membership notifications");

    let rest_client = relay.rest_client();
    let mut author_gate_ctx =
        crate::InboundAuthorGate::connect(&rest_client, &pubkey_hex, "setup startup").await;

    // Resolve owner for author-gate (same priority as normal mode).
    let startup_owner = crate::resolve_agent_owner(&config);

View on GitHub (pinned to dad5a33865)

Solutions

  1. Confirm the relay is running and the URL scheme is explicit: ws://localhost:3000 or wss://host
  2. Check the harness env: BUZZ_RELAY_URL, BUZZ_PRIVATE_KEY, relay auth tag
  3. Test reachability independently (curl the relay's HTTP NIP-11 endpoint on the same host)
  4. Retry after the relay is healthy

Example fix

# before
export BUZZ_RELAY_URL=localhost:3000
# after
export BUZZ_RELAY_URL=ws://localhost:3000
Defensive patterns

Strategy: retry

Validate before calling

#!/usr/bin/env bash
: "${BUZZ_RELAY_URL:?BUZZ_RELAY_URL required for setup mode}"
case "$BUZZ_RELAY_URL" in ws://*|wss://*) ;; *) echo "BUZZ_RELAY_URL must start with ws:// or wss://" >&2; exit 1;; esac
nc -z "$(echo "$BUZZ_RELAY_URL" | sed -E 's|^wss?://||; s|:[0-9]+$||')" "$(echo "$BUZZ_RELAY_URL" | sed -nE 's|.*:([0-9]+)$|\1|p')" \
  || { echo 'relay port not reachable' >&2; exit 1; }

Try / catch

// Retry transient connect failures; fail fast on auth-shaped ones
loop {
    match HarnessRelay::connect(&url, &keys, &pubkey, auth_tag).await {
        Err(e) if is_auth_error(&e) => return Err(e),          // do not retry bad credentials
        Err(_) if attempts < MAX => { backoff.wait().await; }
        other => return other.map(|_| ()),
    }
}

Prevention

When it happens

Trigger: BUZZ_RELAY_URL wrong (typo, missing ws:// or wss:// scheme), relay not running or unreachable, TLS failure on wss://, or the auth handshake rejected due to an invalid/expired auth tag.

Common situations: Local relay not started (just relay missing from the workflow); staging URL changed; auth tag env rotated while the harness kept the old value; firewall/proxy blocking the WebSocket upgrade.

Related errors


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-20). Data as JSON: /api/errors/df1db88f87f3a38d. Report an issue: GitHub.