#7596·buzz

Archived (expired huddle) channel cannot be deleted or unarchived from Desktop: relay returns 400 'channel is archived' for kind 9008 and Desktop's kind 9002

Author: rizqconCreated Sep 11, 2026Updated Sep 17, 2026

Summary

An expired ephemeral channel (huddle, ttl_seconds: 3600) that the relay's reaper has archived can no longer be deleted or unarchived from Buzz Desktop. Desktop shows both Unarchive and Delete channel to the channel owner, but the relay rejects both with 400 Bad Request: invalid: channel is archived. The channel is stuck in the owner's community list forever.

Environment

  • Relay: ghcr.io/block/buzz:main (checkout 0020907), self-hosted, single community, Docker compose.
  • Desktop: current Windows build, owner identity.

Steps to reproduce

  1. As community owner, start a huddle (creates an ephemeral private channel with a 1 h TTL).
  2. Let the TTL expire; the relay archives the channel (archived_at set by the reaper).
  3. In Desktop, open the archived channel → channel management → Delete channel.
  4. Observe the dialog: relay returned 400 Bad Request: invalid: channel is archived.
  5. Try Unarchive in the same sheet → same 400.

Relay log for both attempts (owner pubkey redacted):

"route":"/events","status":400,"accepted":false,"kind":9008,"reason":"invalid: channel is archived"
"route":"/events","status":400,"accepted":false,"kind":9002,"reason":"invalid: channel is archived"

Root cause (as far as I can tell)

crates/buzz-relay/src/handlers/ingest.rs rejects every event targeting an archived channel unless it is a kind:9002 carrying the tag ["archived", "false"]:

rust
let is_unarchive = kind_u32 == KIND_NIP29_EDIT_METADATA
    && event.tags.iter().any(|t| { ... parts[0] == "archived" && parts[1] == "false" });
if !is_unarchive { if channel.archived_at.is_some() { return Err(IngestError::Rejected("invalid: channel is archived".into())); } }
  • kind:9008 (delete) is therefore always refused on an archived channel, yet Desktop offers the action.
  • Desktop's Unarchive sends a kind:9002 that the relay does not recognise as an unarchive (no archived=false tag, or a different shape), so it is refused too.
  • buzz channels unarchive from the CLI does send the expected tag and succeeds, so the CLI can work around it; Desktop users cannot.

Expected

Either of:

  1. Allow kind:9008 on archived channels (deleting an archived channel is the common case, and "archive then delete" is the natural flow), or
  2. Have Desktop hide Delete on archived channels and send a relay-recognised unarchive; and give the reaper-archived ephemeral channels a way out (auto-delete after TTL + grace, or allow the owner to delete).

Workaround used

Cleared archived_at on the row in Postgres, then deleted from Desktop. Not something users should need to do.