Bug: a reaction on a project root (issue/PR) panics the relay's ingest worker
Component: buzz-relay — crates/buzz-relay/src/handlers/ingest.rs, reaction write path
Severity: crash + client livelock (stored-then-panic makes retries permanent)
Symptom
Publishing a NIP-25-style reaction whose target is a project root or project comment (kind 1621 issue, 1618 PR, or a kind-1 comment on one) panics a tokio worker:
thread 'tokio-rt-worker' panicked at crates/buzz-relay/src/handlers/ingest.rs:2824:51:
reaction path has channel
Root cause
The reaction path's conformance-trace emission asserts a channel is always present:
// This branch is the reaction path; channel_id is always Some here, so
// WriteInsertGlobal does not apply.
channel: channel_label(channel_id.expect("reaction path has channel")),
That assumption predates reactions on project events. Project events carry no h tag, so channel_id is None — the expect panics. Two aggravators:
- Stored-then-panic: the reaction row is inserted before the trace action is built, so the client sees a failed request for an event that was actually persisted, and retries.
- The duplicate branch carries the identical
expect, so every retry panics too. A client with a durable, ordered publish queue (e.g. buzz-acp's gated-publish FIFO acknowledging a project dispatch) is head-of-line blocked forever, burning rate-limit quota on a publish that can never be acknowledged.
Any human tapping a reaction on an issue comment in Desktop triggers the same panic.
Fix that worked for us
Mirror the message write's three-way split at the same seam (it already handles channel-less writes a few hundred lines below): (Some, true) → WriteInsert, (Some, false) → WriteDuplicate, (None, _) → WriteInsertGlobal. The conformance vocabulary already models channel-less writes; only the reaction path was missing it.
Reproduction
- Closed or open relay; publish a kind-1621 issue.
- React (kind 7) to the issue root or a comment on it, with no
h tag (as Desktop/agents correctly send for project events).
- Observe the panic in relay logs; observe the reaction IS stored; retry and observe the duplicate-branch panic.
Bug: a reaction on a project root (issue/PR) panics the relay's ingest worker
Component:
buzz-relay—crates/buzz-relay/src/handlers/ingest.rs, reaction write pathSeverity: crash + client livelock (stored-then-panic makes retries permanent)
Symptom
Publishing a NIP-25-style reaction whose target is a project root or project comment (kind 1621 issue, 1618 PR, or a kind-1 comment on one) panics a tokio worker:
Root cause
The reaction path's conformance-trace emission asserts a channel is always present:
That assumption predates reactions on project events. Project events carry no
htag, sochannel_idisNone— theexpectpanics. Two aggravators:expect, so every retry panics too. A client with a durable, ordered publish queue (e.g.buzz-acp's gated-publish FIFO acknowledging a project dispatch) is head-of-line blocked forever, burning rate-limit quota on a publish that can never be acknowledged.Any human tapping a reaction on an issue comment in Desktop triggers the same panic.
Fix that worked for us
Mirror the message write's three-way split at the same seam (it already handles channel-less writes a few hundred lines below):
(Some, true) → WriteInsert,(Some, false) → WriteDuplicate,(None, _) → WriteInsertGlobal. The conformance vocabulary already models channel-less writes; only the reaction path was missing it.Reproduction
htag (as Desktop/agents correctly send for project events).