zed-industries/zed · error
not a room participant
Error message
not a room participant
What it means
Thrown by room_connection_ids when, after scanning all room_participant rows, the calling connection_id does not match any participant's answering_connection. The function both collects the other participants' connection ids and asserts membership; if this connection has no answering connection registered in the room, the caller is not an active participant.
Source
Thrown at crates/collab/src/db/queries/rooms.rs:1304
.filter(room_participant::Column::RoomId.eq(room_id))
.stream(&*tx)
.await?;
let mut is_participant = false;
let mut connection_ids = HashSet::default();
while let Some(participant) = participants.next().await {
let participant = participant?;
if let Some(answering_connection) = participant.answering_connection() {
if answering_connection == connection_id {
is_participant = true;
} else {
connection_ids.insert(answering_connection);
}
}
}
if !is_participant {
Err(anyhow!("not a room participant"))?;
}
Ok(connection_ids)
})
.await
}
async fn get_channel_room(
&self,
room_id: RoomId,
tx: &DatabaseTransaction,
) -> Result<(Option<channel::Model>, proto::Room)> {
let db_room = room::Entity::find_by_id(room_id)
.one(tx)
.await?
.context("could not find room")?;
let mut db_participants = db_roomView on GitHub (pinned to bc538def45)
Solutions
- Ensure the connection issuing room operations is the one that joined (answered) the room; rejoin the room from this connection first
- Wait for the join_room/rejoin_room response before sending further room-scoped requests on that connection
- On reconnect, invalidate room membership state and re-establish it before any dependent RPC
Example fix
// before
let peers = client.room_connection_ids(room_id, connection_id).await?;
// after (verify membership first)
if !self.joined_rooms.contains(&room_id) {
client.join_room(room_id, connection_id).await?;
self.joined_rooms.insert(room_id);
}
let peers = client.room_connection_ids(room_id, connection_id).await?; Defensive patterns
Strategy: validation
Validate before calling
// Ensure this connection is an active participant before room-scoped calls.
if !self.joined_rooms.contains(&room_id) {
client.join_room(room_id, my_connection_id).await?;
self.joined_rooms.insert(room_id);
}
let peers = client.room_connection_ids(room_id, my_connection_id).await?; Try / catch
match client.room_connection_ids(room_id, my_connection_id).await {
Ok(ids) => Ok(ids),
Err(err) if err.to_string().contains("not a room participant") => {
client.join_room(room_id, my_connection_id).await?; // rejoin then retry once
client.room_connection_ids(room_id, my_connection_id).await
}
Err(err) => Err(err),
} Prevention
- Issue room operations from the connection that answered the join
- Wait for the join_room response before dependent room RPCs
- On reconnect, rebuild room membership state per connection before any room-scoped request
When it happens
Trigger: Issuing a room-scoped RPC that resolves other participants (e.g. room messaging/leaving flows) from a connection that never called join_room or whose answering_connection is still null (pending ring not yet answered); the same user participating from another connection/device; reconnected with a new ConnectionId without rejoining.
Common situations: Multi-device usage where one window joined the room but another issues the room operation; reconnect logic that reuses old room state with a fresh connection; acting on a room before the join handshake completes.
Related errors
- banned users cannot invite
- user has not signed the Zed CLA
- guests cannot share projects
- not authorized to edit projects
- not authorized to read projects
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/3cb523d56a1a269a.
Report an issue: GitHub.