Skip to content

RoomInfo.pinnedEventIds is empty for rooms with server-side m.room.pinned_events state #56

Description

@hamiltonchua

Summary

Room.roomInfo() returns pinnedEventIds: [] for rooms that have a valid server-side m.room.pinned_events state event with pinned events in it. This is observable even in the initial baseline snapshot right after the room is opened — not a "state not loaded yet" race.

Environment

  • Package: @unomed/react-native-matrix-sdk 0.9.1
  • Runtime: React Native 0.7x (Expo dev client), Android emulator
  • Homeserver: Synapse 1.156.0 behind Matrix Authentication Service (MAS)
  • Room: !QqqEqsAgTkbdletaNs:muni.rappler.com with m.room.pinned_events containing 3 event IDs at the time of testing

Repro

  1. Join a room that has pinned messages (verify via GET /_matrix/client/v3/rooms/{roomId}/state/m.room.pinned_events — returns {"pinned": ["$evt1", "$evt2", ...]}).
  2. In the app, read Room.roomInfo().pinnedEventIds immediately after room open (baseline snapshot) and after subsequent room-info updates.
  3. Observed: pinnedEventIds is [] in every snapshot, while the server state endpoint returns the 3 pinned IDs.

Related observation: Timeline.pinEvent(eventId) can return false when the SDK's stale local state believes the event is already pinned — which makes pin/unpin actions look like silent no-ops.

Expected

RoomInfo.pinnedEventIds should match the server-side m.room.pinned_events content.

Useful context for triage

The timeline diff surface DOES deliver m.room.pinned_events changes correctly: a pin made by another member produces a TimelineItemContent.State item with inner.content.tag === 'RoomPinnedEvents' in the Timeline.addListener diff within seconds (verified live). So the state-event pipeline works; the RoomInfo cache path appears to be the broken piece.

Workaround (current)

Because the field is unreliable, we read the authoritative list directly from the homeserver state endpoint and refresh when a RoomPinnedEvents state item arrives in the timeline diff, with a periodic poll as a backstop. A fix to RoomInfo.pinnedEventIds (or an explicit "this field is not populated" documentation) would let clients drop the workaround.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions