zed-industries/zed · error · Error::Internal
banned users cannot invite
Error message
banned users cannot invite
What it means
Thrown by rooms call() when the calling user's room_participant role is ChannelRole::Banned. Before creating a participant row for the called user, the server maps the caller's role to the role the invitee will get (Admin/Member -> Member, Guest/Talker -> Guest); a Banned caller is rejected outright because banned participants may not invite anyone into the room.
Source
Thrown at crates/collab/src/db/queries/rooms.rs:169
calling_connection: ConnectionId,
called_user_id: UserId,
initial_project_id: Option<ProjectId>,
) -> Result<TransactionGuard<(proto::Room, proto::IncomingCall)>> {
self.room_transaction(room_id, |tx| async move {
let caller = room_participant::Entity::find()
.filter(
room_participant::Column::UserId
.eq(calling_user_id)
.and(room_participant::Column::RoomId.eq(room_id)),
)
.one(&*tx)
.await?
.context("user is not in the room")?;
let called_user_role = match caller.role.unwrap_or(ChannelRole::Member) {
ChannelRole::Admin | ChannelRole::Member => ChannelRole::Member,
ChannelRole::Guest | ChannelRole::Talker => ChannelRole::Guest,
ChannelRole::Banned => return Err(anyhow!("banned users cannot invite").into()),
};
room_participant::ActiveModel {
room_id: ActiveValue::set(room_id),
user_id: ActiveValue::set(called_user_id),
answering_connection_lost: ActiveValue::set(false),
participant_index: ActiveValue::NotSet,
calling_user_id: ActiveValue::set(calling_user_id),
calling_connection_id: ActiveValue::set(calling_connection.id as i32),
calling_connection_server_id: ActiveValue::set(Some(ServerId(
calling_connection.owner_id as i32,
))),
initial_project_id: ActiveValue::set(initial_project_id),
role: ActiveValue::set(Some(called_user_role)),
id: ActiveValue::NotSet,
answering_connection_id: ActiveValue::NotSet,
answering_connection_server_id: ActiveValue::NotSet,View on GitHub (pinned to bc538def45)
Solutions
- Have a room Admin unban the caller's user, then retry the call
- Create or use a different room the caller legitimately participates in
- Refresh room state after moderation events and disable invite/call actions for rooms where the caller is banned
Example fix
// before
client.call_user(room_id, called_user_id, initial_project_id).await?;
// after (guard on own role)
let room = client.get_room(room_id).await?;
let my_role = room.participants.iter().find(|p| p.user_id == my_user_id).and_then(|p| p.role);
if my_role == Some(proto::ChannelRole::Banned) {
return Err(anyhow!("cannot invite into a room you are banned from"));
}
client.call_user(room_id, called_user_id, initial_project_id).await?; Defensive patterns
Strategy: validation
Validate before calling
// Do not attempt to invite/call into rooms where you are banned.
let my_role = room.participants.iter()
.find(|p| p.user_id == my_user_id)
.and_then(|p| p.role);
if my_role == Some(proto::ChannelRole::Banned) {
self.ui.show_toast("You are banned from this room");
return Ok(());
}
client.call_user(room_id, called_user_id, initial_project_id).await?; Type guard
fn is_banned(participants: &[proto::RoomParticipant], user_id: u64) -> bool {
participants.iter().any(|p| p.user_id == user_id && p.role == Some(proto::ChannelRole::Banned))
} Try / catch
if let Err(err) = client.call_user(room_id, called_user_id, None).await {
if err.to_string().contains("banned users cannot invite") {
self.disable_call_button(room_id);
}
return Err(err);
} Prevention
- Disable invite/call actions in rooms where your own role is Banned
- Refresh room state after moderation events (kick/ban) and update the UI immediately
- Prefer creating a fresh room over reusing one you were removed from
When it happens
Trigger: CallUser (call RPC) issued with a room_id in which the caller's participant row has role Banned; caller was banned mid-call and then tries to ring another contact into the same room.
Common situations: Moderators ban a disruptive user whose client still has the room open; the banned user's UI still shows call/invite buttons for that room; stale room state after being removed from a channel.
Related errors
- could not find call to decline
- room does not exist or was already joined
- user has not signed the Zed CLA
- not a room participant
- cannot call a user who isn't a contact
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/9e135fa9aebf589c.
Report an issue: GitHub.