diff --git a/src/cli/repair.rs b/src/cli/repair.rs index ab085a00..88c3fb69 100644 --- a/src/cli/repair.rs +++ b/src/cli/repair.rs @@ -18,7 +18,9 @@ use petgraph::{ }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use ruma::{ - events::{room::member::MembershipState, StateEventType}, + events::{ + room::member::MembershipState, StateEventType, TimelineEventType, + }, state_res::StateMap, EventId, RoomId, RoomVersionId, UserId, }; @@ -441,8 +443,26 @@ fn get_state_event_graphs( return None; }; - // Filter out non-state events - pdu.state_key?; + let Some(state_key) = pdu.state_key else { + // Filter out non-state events + return None; + }; + + // Ruma fails the entire state resolution if it sees an event whose + // `state_key` it needs to parse as an ID and the parsing fails, so + // we pre-emptively drop these events. Real-world cases where this + // has happened are detailed on the issue linked below. + // + // + if pdu.kind == TimelineEventType::RoomMember + && <&UserId>::try_from(&*state_key).is_err() + { + t::warn!( + event_id = %pdu.event_id, + "Dropping event that could cause state resolution to fail", + ); + return None; + } Some(( >::from(pdu.room_id),