zed-industries/zed · error · Error::Internal
no such member
Error message
no such member
What it means
Thrown by remove_channel_member (crates/collab/src/db/queries/channels.rs:490) when the DELETE of the channel_member row for (channel_id, member_id) affects 0 rows — the target user has no membership row in that channel, whether never a member or already removed.
Source
Thrown at crates/collab/src/db/queries/channels.rs:490
self.transaction(|tx| async move {
let channel = self.get_channel_internal(channel_id, &tx).await?;
if member_id != admin_id {
self.check_user_is_channel_admin(&channel, admin_id, &tx)
.await?;
}
let result = channel_member::Entity::delete_many()
.filter(
channel_member::Column::ChannelId
.eq(channel_id)
.and(channel_member::Column::UserId.eq(member_id)),
)
.exec(&*tx)
.await?;
if result.rows_affected == 0 {
Err(anyhow!("no such member"))?;
}
Ok(RemoveChannelMemberResult {
membership_update: self
.calculate_membership_updated(&channel, member_id, &tx)
.await?,
notification_id: self
.remove_notification(
member_id,
rpc::Notification::ChannelInvitation {
channel_id: channel_id.to_proto(),
channel_name: Default::default(),
inviter_id: Default::default(),
},
&tx,
)
.await?,
})View on GitHub (pinned to bc538def45)
Solutions
- Refresh the member list from the latest membership_update notification before offering the remove action
- Treat the error as benign when the member is already gone (idempotent removal) and drop the notification cleanup accordingly
- Verify the member_id being sent is the one from the roster entry, not a user id from another context
Defensive patterns
Strategy: validation
Validate before calling
// Verify membership before issuing the kick
if channel_members.contains_key(&member_id) {
db.remove_channel_member(channel_id, member_id, admin_id).await?;
} Try / catch
// Kicking an already-gone member is a no-op
match db.remove_channel_member(channel_id, member_id, admin_id).await {
Ok(result) => Ok(Some(result)),
Err(err) if err.to_string().contains("no such member") => Ok(None),
Err(err) => Err(err),
} Prevention
- Render admin kick actions from the latest membership_update, not a cached roster
- Coordinate concurrent admins: expect one of two racing kicks to see 'no such member'
- Include member ids (not display names) in remove requests to avoid mismatches
When it happens
Trigger: Admin calls remove-member for a user who already left the channel; removing a user whose invitation was revoked (pending row deleted); two admins racing to kick the same member; client UI showing a stale member list.
Common situations: Stale channel roster in the client after a membership_update event was dropped; kick + auto-leave racing; retry of a remove that already succeeded.
Related errors
- not a collaborator on this project
- can't delete channel while a call is in progress
- channel name can't be blank
- no such invitation
- user is not a channel admin or channel does not exist
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/5fd0485f5a456fa3.
Report an issue: GitHub.