{"record":{"id":"dd462a22c2acfd22","repo":"zed-industries/zed","slug":"tried-to-join-channel-call-directly","errorCode":null,"errorMessage":"tried to join channel call directly","messagePattern":"tried to join channel call directly","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/collab/src/db/queries/rooms.rs","lineNumber":316,"sourceCode":"        connection: ConnectionId,\n    ) -> Result<TransactionGuard<JoinRoom>> {\n        self.room_transaction(room_id, |tx| async move {\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            enum QueryChannelId {\n                ChannelId,\n            }\n\n            let channel_id: Option<ChannelId> = room::Entity::find()\n                .select_only()\n                .column(room::Column::ChannelId)\n                .filter(room::Column::Id.eq(room_id))\n                .into_values::<_, QueryChannelId>()\n                .one(&*tx)\n                .await?\n                .context(\"no such room\")?;\n\n            if channel_id.is_some() {\n                Err(anyhow!(\"tried to join channel call directly\"))?\n            }\n\n            let participant_index = self\n                .get_next_participant_index_internal(room_id, &tx)\n                .await?;\n\n            let result = room_participant::Entity::update_many()\n                .filter(\n                    Condition::all()\n                        .add(room_participant::Column::RoomId.eq(room_id))\n                        .add(room_participant::Column::UserId.eq(user_id))\n                        .add(room_participant::Column::AnsweringConnectionId.is_null()),\n                )\n                .set(room_participant::ActiveModel {\n                    participant_index: ActiveValue::Set(Some(participant_index)),\n                    answering_connection_id: ActiveValue::set(Some(connection.id as i32)),\n                    answering_connection_server_id: ActiveValue::set(Some(ServerId(\n                        connection.owner_id as i32,","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/collab/src/db/queries/rooms.rs#L298-L334","documentation":"join_room detects that the target room belongs to a channel; channel rooms cannot be joined directly by room ID — clients must join through the channel mechanism so channel membership and roles are enforced.","triggerScenarios":"Thrown at crates/collab/src/db/queries/rooms.rs:316 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Join via the channel (e.g. join_channel_buffer) instead of the raw room ID","For direct rooms or DMs, use the normal room join flow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}