I've been running a WhatsApp <-> Matrix <-> Signal relay setup for quite a while now and ran into what I think is a gap in the current relay handling. Polls sent from WhatsApp make it into Matrix just fine as org.matrix.msc3381.poll.start events, but they never show up on Signal, no error, no notice in the room, nothing. It took me a while to even figure out what was happening. (Signal to Matrix is just a normal text message)
- mautrix-whatsapp bridging WhatsApp into Matrix
- mautrix-signal bridging the same Matrix room to Signal
- Relay mode enabled on both bridges, sharing the same Matrix room
extev_polls: true enabled
But when I send a poll in WhatsApp in a group that is shared/relayed to Signal. I observe that the poll correctly arrives in Matrix as org.matrix.msc3381.poll.start, but that the poll does not appear on Signal
The poll should show up on, just like regular text messages from the same ghost user do.
The Signal bridge logs show:
DBG Ignoring poll event from relayed user
action="handle matrix event"
event_type=org.matrix.msc3381.poll.start
sender=@whatsapp_lid-XXXXXXX:some.tld
The event is decrypted successfully but then explicitly dropped because the sender is identified as a ghost/relay user rather than a real Matrix user.
AI-Assisted Code Lookup
Note: The following section was generated with AI assistance after tracing through the source code.
The drop is in bridgev2/portal.go around line 1163:
// bridgev2/portal.go
if origSender != nil {
if msgContent == nil {
log.Debug().Msg("Ignoring poll event from relayed user")
return EventHandlingResultIgnored.WithMSSError(ErrIgnoringPollFromRelayedUser)
}
if !caps.PerMessageProfileRelay {
msgContent, err = portal.Bridge.Config.Relay.FormatMessage(msgContent, origSender)
...
}
}
Why this triggers for polls specifically:
Earlier in the same handler, the event content is resolved into one of three separate typed variables:
| Event type |
Variable set |
m.room.message / sticker |
msgContent ✅ |
org.matrix.msc3381.poll.start |
pollContent |
org.matrix.msc3381.poll.response |
pollResponseContent |
When a poll event arrives, msgContent is nil and only pollContent is populated. The relay path then hits origSender != nil && msgContent == nil which is exactly the condition that fires when a ghost/bridge user sends a poll and immediately returns EventHandlingResultIgnored.
Regular messages work fine because msgContent is not nil for them, so they fall through to the FormatMessage relay formatting step (which prepends the ghost user's display name) and continue to be forwarded.
The error is defined in bridgev2/errors.go:
ErrIgnoringPollFromRelayedUser error = WrapErrorInStatus(
errors.New("ignoring poll event from relayed user"),
).WithIsCertain(true).WithSendNotice(false)
The WithSendNotice(false) is why there is no visible error message in the Matrix room — the drop is completely silent from a user perspective.
Root cause summary: There is no relay formatting path for poll content types. The relay logic in bridgev2 only knows how to prepend sender info to *event.MessageEventContent. No equivalent exists for *event.PollStartEventContent, so poll events from relayed users are unconditionally dropped rather than forwarded.
Feature Request
Please add a configuration option to allow poll events from relayed/ghost users to be forwarded. For example:
network:
extev_polls: true
relay_extev_polls: true # new: allow polls from ghost users to be relayed
Alternatively, treating poll events from ghost users the same way regular messages from ghost users are treated, forwarding them as native Signal polls without relay-prefix formatting.
I've been running a WhatsApp <-> Matrix <-> Signal relay setup for quite a while now and ran into what I think is a gap in the current relay handling. Polls sent from WhatsApp make it into Matrix just fine as
org.matrix.msc3381.poll.startevents, but they never show up on Signal, no error, no notice in the room, nothing. It took me a while to even figure out what was happening. (Signal to Matrix is just a normal text message)extev_polls: trueenabledBut when I send a poll in WhatsApp in a group that is shared/relayed to Signal. I observe that the poll correctly arrives in Matrix as
org.matrix.msc3381.poll.start, but that the poll does not appear on SignalThe poll should show up on, just like regular text messages from the same ghost user do.
The Signal bridge logs show:
The event is decrypted successfully but then explicitly dropped because the sender is identified as a ghost/relay user rather than a real Matrix user.
AI-Assisted Code Lookup
The drop is in
bridgev2/portal.goaround line 1163:Why this triggers for polls specifically:
Earlier in the same handler, the event content is resolved into one of three separate typed variables:
m.room.message/ stickermsgContent✅org.matrix.msc3381.poll.startpollContentorg.matrix.msc3381.poll.responsepollResponseContentWhen a poll event arrives,
msgContentis nil and onlypollContentis populated. The relay path then hitsorigSender != nil && msgContent == nilwhich is exactly the condition that fires when a ghost/bridge user sends a poll and immediately returnsEventHandlingResultIgnored.Regular messages work fine because
msgContentis not nil for them, so they fall through to theFormatMessagerelay formatting step (which prepends the ghost user's display name) and continue to be forwarded.The error is defined in
bridgev2/errors.go:The
WithSendNotice(false)is why there is no visible error message in the Matrix room — the drop is completely silent from a user perspective.Root cause summary: There is no relay formatting path for poll content types. The relay logic in
bridgev2only knows how to prepend sender info to*event.MessageEventContent. No equivalent exists for*event.PollStartEventContent, so poll events from relayed users are unconditionally dropped rather than forwarded.Feature Request
Please add a configuration option to allow poll events from relayed/ghost users to be forwarded. For example:
Alternatively, treating poll events from ghost users the same way regular messages from ghost users are treated, forwarding them as native Signal polls without relay-prefix formatting.