zed-industries/zed · warning
user was already invited
Error message
user was already invited
What it means
ActiveCall::invite de-duplicates concurrent invites with a pending_invites set; inserting a called_user_id that is already pending returns this error immediately from a ready task, without contacting the server.
Source
Thrown at crates/call/src/call_impl/mod.rs:493
}
pub fn global(cx: &App) -> Entity<Self> {
Self::try_global(cx).unwrap()
}
pub fn try_global(cx: &App) -> Option<Entity<Self>> {
let any = cx.try_global::<GlobalAnyActiveCall>()?;
any.0.entity().downcast::<Self>().ok()
}
pub fn invite(
&mut self,
called_user_id: u64,
initial_project: Option<Entity<Project>>,
cx: &mut Context<Self>,
) -> Task<Result<()>> {
if !self.pending_invites.insert(called_user_id) {
return Task::ready(Err(anyhow!("user was already invited")));
}
cx.notify();
if self._join_debouncer.running() {
return Task::ready(Ok(()));
}
let room = if let Some(room) = self.room().cloned() {
Some(Task::ready(Ok(room)).shared())
} else {
self.pending_room_creation.clone()
};
let invite = if let Some(room) = room {
cx.spawn(async move |_, cx| {
let room = room.await.map_err(|err| anyhow!("{err:?}"))?;
let initial_project_id = if let Some(initial_project) = initial_project {View on GitHub (pinned to bc538def45)
Solutions
- Await (or track) the first invite task before issuing another for the same user.
- Disable or debounce the invite button while an invite is pending.
- Treat the error as an idempotent no-op when the intent was a duplicate retry.
Example fix
// before: fire-and-forget, duplicate clicks double-invite
call.update(cx, |c, cx| c.invite(user_id, project, cx));
// after: track in-flight invites and short-circuit duplicates
if invite_in_flight.contains(&user_id) {
return Task::ready(Ok(()));
}
invite_in_flight.insert(user_id);
call.update(cx, |c, cx| c.invite(user_id, project, cx)) Defensive patterns
Strategy: validation
Validate before calling
if invite_in_flight.contains(&called_user_id) {
return Task::ready(Ok(())); // idempotent no-op
}
invite_in_flight.insert(called_user_id);
let task = call.update(cx, |call, cx| call.invite(called_user_id, project, cx));
// remove from invite_in_flight when the task completes Try / catch
match invite-task errors containing "user was already invited" and map them to Ok(()) - the invite is already in flight, so treat it as success in the UI.
Prevention
- Disable invite buttons while the invite task runs
- Track in-flight invites per user in UI state
- Await the first invite task before retrying
When it happens
Trigger: Calling invite(user_id, ...) twice before the first invite task completes - double-click on a call button, duplicated UI events, or programmatic retries that do not await the first Task.
Common situations: UI buttons firing twice; retry wrappers re-invoking invite without awaiting; rapid successive calls to the same person.
Related errors
- not in a call
- {err:?}
- HTTP error! status: ${response.status}
- Context server not initialized
- MCP tool cancelled by user
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/5b71e8da2e431e75.
Report an issue: GitHub.