block/buzz · error · anyhow::Error

setup-mode membership subscribe error

Error message

setup-mode membership subscribe error: {e}

What it means

In setup mode the relay connection succeeded, but subscribe_membership_notifications — the REQ that feeds the setup flow its membership events — failed (rejected REQ or closed socket). Because membership notifications are setup mode's core input, the harness aborts right after connecting and setting the startup watermark.

Solutions

  1. Confirm the relay build supports membership notifications (same version family as the harness)
  2. Verify the auth env vars give the harness subscription access to the community
  3. Retry startup after fixing connectivity; check relay logs for the closed REQ
Defensive patterns

Strategy: retry

Validate before calling

# Preflight: relay up AND same version family as the harness before setup mode
curl -fsS "$(echo "$BUZZ_RELAY_URL" | sed 's|^ws\(s\)\?://|http\1://')/" | grep -q '"name"' \
  || { echo 'relay not serving NIP-11 metadata' >&2; exit 1; }

Try / catch

// Connect and subscribe inside one retry envelope — a drop between them is transient
for attempt in 1..=3 {
    let mut relay = HarnessRelay::connect(...).await?;
    match relay.subscribe_membership_notifications().await {
        Ok(()) => break,
        Err(e) if attempt < 3 => { tokio::time::sleep(Duration::from_secs(attempt)).await; }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: The relay closes or errors the membership-notifications REQ: an older relay without this subscription type, an auth token without community membership scope, or a connection drop immediately after connect. Note the preceding set_startup_watermark failure only warns — this subscribe failure is the fatal one.

Common situations: Staging relay version older than the harness; expired NIP-42 auth tag granting no subscription rights; flaky network between harness and relay at startup.

Related errors


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

Appendix: source

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

        .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);
    let owner_cache = crate::OwnerCache::new(startup_owner);

    // Discover channels and subscribe (using a "mentions" rule so we get
    // notified when someone @-mentions the agent).
    let channel_info_map = relay
        .discover_channels()
        .await
        .map_err(|e| anyhow::anyhow!("setup-mode channel discovery error: {e}"))?;

View on GitHub (pinned to 6c35e82bd5)