Skip to content

fix(relay): guard multi-value #h filters from collapsing to one channel - #4693

Open
santhiprakash wants to merge 1 commit into
block:mainfrom
santhiprakash:fix/query-h-filter-arity
Open

fix(relay): guard multi-value #h filters from collapsing to one channel#4693
santhiprakash wants to merge 1 commit into
block:mainfrom
santhiprakash:fix/query-h-filter-arity

Conversation

@santhiprakash

Copy link
Copy Markdown

Summary

extract_channel_id_from_filter in crates/buzz-relay/src/handlers/req.rs previously returned the first parseable UUID out of a multi-value #h tag. This caused POST /query filters listing multiple channel UUIDs to silently collapse to whichever channel sorted first in generic_tags, turning a NIP-01 OR-semantics filter into an AND-of-one against a single arbitrary channel before the correct filters_match post-filter could run.

This change adds the same arity guard already present in bridge.rs::extract_channel_from_filter and in the WS REQ path (extract_channel_id_from_filters): channel_id is only set when the filter contains exactly one #h value and it is a parseable UUID. Multi-value #h filters now leave channel_id unset so the existing Rust-side post-filter handles the OR semantics correctly.

Related issue

Fixes #4659

Testing

  • cargo test -p buzz-relay handlers::req — all 52 tests pass, including 5 new focused regression tests:
    • extract_channel_id_from_filter_single_h
    • extract_channel_id_from_filter_multi_h_returns_none
    • extract_channel_id_from_filter_no_h_returns_none
    • extract_channel_id_from_filter_invalid_h_returns_none
    • build_event_query_from_filter_multi_h_leaves_channel_id_unset
  • cargo fmt --all -- --check passes
  • cargo clippy -p buzz-relay --all-targets --all-features -- -D warnings passes

extract_channel_id_from_filter previously returned the first parseable UUID from a multi-value #h tag, so a POST /query filter listing multiple channel UUIDs silently collapsed to whichever channel sorted first. NIP-01 treats a multi-value tag as OR, so the filter must be handled by the Rust-side filters_match post-filter instead of being pinned to a single channel_id SQL predicate.

Match the existing guard in bridge.rs::extract_channel_from_filter and the WS REQ path: only set channel_id when the filter contains exactly one #h value and it is a parseable UUID. Add focused regression tests.

Fixes block#4659

Signed-off-by: Santhi Prakash <b.santhiprakash@gmail.com>
@santhiprakash
santhiprakash requested a review from a team as a code owner August 4, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTP bridge /query silently scopes multi-value #h filters to a single channel (breaks desktop Workflows list)

1 participant