{"record":{"id":"66064b7d9f93a482","repo":"zed-industries/zed","slug":"not-in-a-call","errorCode":null,"errorMessage":"not in a call","messagePattern":"not in a call","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/call/src/call_impl/mod.rs","lineNumber":205,"sourceCode":"    fn most_active_project(&self, cx: &App) -> Option<(u64, u64)> {\n        let room = self.0.read(cx).room()?;\n        room.read(cx).most_active_project(cx)\n    }\n\n    fn share_project(&self, project: Entity<Project>, cx: &mut App) -> Task<Result<u64>> {\n        self.0\n            .update(cx, |this, cx| this.share_project(project, cx))\n    }\n\n    fn join_project(\n        &self,\n        project_id: u64,\n        language_registry: Arc<language::LanguageRegistry>,\n        fs: Arc<dyn fs::Fs>,\n        cx: &mut App,\n    ) -> Task<Result<Entity<Project>>> {\n        let Some(room) = self.0.read(cx).room().cloned() else {\n            return Task::ready(Err(anyhow::anyhow!(\"not in a call\")));\n        };\n        room.update(cx, |room, cx| {\n            room.join_project(project_id, language_registry, fs, cx)\n        })\n    }\n\n    fn peer_id_for_user_in_room(&self, user_id: u64, cx: &App) -> Option<proto::PeerId> {\n        let room = self.0.read(cx).room()?.read(cx);\n        room.remote_participants()\n            .values()\n            .find(|p| p.user.legacy_id == user_id)\n            .map(|p| p.peer_id)\n    }\n\n    fn subscribe(\n        &self,\n        window: &mut Window,\n        cx: &mut Context<Workspace>,","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/call/src/call_impl/mod.rs#L187-L223","documentation":"The collab ServerContext implementation for ActiveCall::join_project requires an active room; when the call entity has no room set (never joined, already left, or room creation still pending), the request is rejected with this error before touching the room.","triggerScenarios":"A join-project RPC arrives while self.0.read(cx).room() is None - the user hung up just before the request, room creation has not finished, or the room was torn down after a disconnect.","commonSituations":"Races between leave_call/hang-up and in-flight join-project requests; clicking a shared-project action during reconnect; clients that keep sending requests after the room ended.","solutions":["Treat it as a benign race in callers: check the call/room state before dispatching join_project.","Re-join the call first, then retry the project join.","If persistent, inspect the collab connection state (reconnect, re-auth) before retrying."],"exampleFix":"// before: fire the request blindly\nlet task = call.join_project(project_id, registry, fs, cx);\n\n// after: guard on room state first\nif call.read(cx).room().is_none() {\n    return Task::ready(Err(anyhow::anyhow!(\"not in a call\")));\n}\nlet task = call.join_project(project_id, registry, fs, cx);","handlingStrategy":"validation","validationCode":"if call.read(cx).room().is_none() {\n    // skip the request or re-join the call first, instead of firing join_project\n    return Task::ready(Err(anyhow::anyhow!(\"not in a call\")));\n}\nlet task = call.join_project(project_id, language_registry, fs, cx);","typeGuard":"fn is_in_call(call: &Entity<ActiveCall>, cx: &App) -> bool {\n    call.read(cx).room().is_some()\n}","tryCatchPattern":"treat Err(\"not in a call\") from join_project as a benign race: drop the pending request and refresh call state instead of surfacing a hard error to the user.","preventionTips":["Re-check room state after async boundaries before sending room-scoped RPCs","Debounce join actions during hang-up/reconnect","Reconcile UI from the error response rather than assuming success"],"tags":["call","collab","race-condition","room","protocol"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}