{"record":{"id":"3190c4802c9f7737","repo":"zed-industries/zed","slug":"not-authorized-to-read-projects","errorCode":null,"errorMessage":"not authorized to read projects","messagePattern":"not authorized to read projects","errorType":"validation","errorClass":"Error::Internal","httpStatus":null,"severity":"error","filePath":"crates/collab/src/db/queries/projects.rs","lineNumber":1142,"sourceCode":"                .filter(room_participant::Column::AnsweringConnectionId.eq(connection_id.id))\n                .one(tx)\n                .await?\n                .and_then(|participant| participant.role)\n        } else {\n            None\n        };\n\n        let role = role_from_room.unwrap_or(ChannelRole::Banned);\n\n        match capability {\n            Capability::ReadWrite => {\n                if !role.can_edit_projects() {\n                    return Err(anyhow!(\"not authorized to edit projects\"))?;\n                }\n            }\n            Capability::ReadOnly => {\n                if !role.can_read_projects() {\n                    return Err(anyhow!(\"not authorized to read projects\"))?;\n                }\n            }\n        }\n\n        Ok((project, role))\n    }\n\n    /// Returns the host connection for a read-only request to join a shared project.\n    pub async fn host_for_read_only_project_request(\n        &self,\n        project_id: ProjectId,\n        connection_id: ConnectionId,\n    ) -> Result<ConnectionId> {\n        self.project_transaction(project_id, |tx| async move {\n            let (project, _) = self\n                .access_project(project_id, connection_id, Capability::ReadOnly, &tx)\n                .await?;\n            project.host_connection()","sourceCodeStart":1124,"sourceCodeEnd":1160,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/collab/src/db/queries/projects.rs#L1124-L1160","documentation":"Thrown during project join authorization when the requested capability is Capability::ReadOnly and the caller's channel role cannot even read projects (role.can_read_projects() is false). Banned is the only role that fails this check, and it is also the default when the caller has no room_participant row at all, so this usually means the user is not in the room where the project is shared.","triggerScenarios":"JoinProject for a project shared in a room the caller never joined; the caller was banned from the room; the caller's participant row was deleted (kicked) before the join arrived.","commonSituations":"Joining a project by URL or ID without first accepting the room invitation; being kicked from a room while the project link is still open; clients that skip the room-join step of the share flow.","solutions":["Join the containing room (accept the invitation / call) before issuing JoinProject for the shared project","Ask a room Admin to lift the ban on the caller's user","Re-request an invitation to the room and then retry the project join"],"exampleFix":"// before\nlet joined = client.join_project(project_id, read_only).await?;\n\n// after (join room first)\nclient.join_room(room_id).await?; // ensures a participant row with a valid role\nlet joined = client.join_project(project_id, read_only).await?;","handlingStrategy":"validation","validationCode":"// Join the room before joining a project shared within it.\nif !self.joined_rooms.contains(&room_id) {\n    client.join_room(room_id, my_connection_id).await?;\n}\nclient.join_project(project_id, capability).await?;","typeGuard":null,"tryCatchPattern":"match client.join_project(project_id, false).await {\n    Ok(joined) => Ok(joined),\n    Err(err) if err.to_string().contains(\"not authorized to read projects\") => {\n        self.ui.show_toast(\"Join the room or ask to be unbanned first\");\n        Ok(default_join()) // or return a typed 'Unauthorized' to the caller\n    }\n    Err(err) => Err(err),\n}","preventionTips":["Always complete the room invitation/join flow before opening shared projects","Check the user's participant/ban state in the room before showing join-project UI","Handle kick/ban room updates by closing dependent project views"],"tags":["authorization","roles","collab","rooms","join-project"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}