zed-industries/zed · error · Error::Internal
not authorized to edit projects
Error message
not authorized to edit projects
What it means
Thrown during project join authorization when the requested capability is Capability::ReadWrite but the caller's channel role cannot edit projects (role.can_edit_projects() is false). The role is taken from the caller's room_participant row; a missing participant row defaults to ChannelRole::Banned. Guest, Talker, and Banned roles are read-only in shared projects.
Source
Thrown at crates/collab/src/db/queries/projects.rs:1137
.context("no such project")?;
let role_from_room = if let Some(room_id) = project.room_id {
room_participant::Entity::find()
.filter(room_participant::Column::RoomId.eq(room_id))
.filter(room_participant::Column::AnsweringConnectionId.eq(connection_id.id))
.one(tx)
.await?
.and_then(|participant| participant.role)
} else {
None
};
let role = role_from_room.unwrap_or(ChannelRole::Banned);
match capability {
Capability::ReadWrite => {
if !role.can_edit_projects() {
return Err(anyhow!("not authorized to edit projects"))?;
}
}
Capability::ReadOnly => {
if !role.can_read_projects() {
return Err(anyhow!("not authorized to read projects"))?;
}
}
}
Ok((project, role))
}
/// Returns the host connection for a read-only request to join a shared project.
pub async fn host_for_read_only_project_request(
&self,
project_id: ProjectId,
connection_id: ConnectionId,
) -> Result<ConnectionId> {View on GitHub (pinned to bc538def45)
Solutions
- Retry the join with Capability::ReadOnly when the caller only needs to view the project
- Have a room Admin promote the user to Member/Admin so can_edit_projects() becomes true
- Join the room through a normal invitation so the caller gets Member role rather than Guest
Example fix
// before
let (_, replica_id) = client.join_project(project_id, /* read_write */ true).await?;
// after (fall back to read-only join)
let (_, replica_id) = match client.join_project(project_id, true).await {
Ok(joined) => joined,
Err(err) if err.to_string().contains("not authorized to edit projects") => {
client.join_project(project_id, false).await?
}
Err(err) => return Err(err),
}; Defensive patterns
Strategy: validation
Validate before calling
// Derive the requested capability from the caller's room role.
let my_role = room.participants.iter()
.find(|p| p.user_id == my_user_id)
.and_then(|p| p.role)
.unwrap_or(proto::ChannelRole::Banned);
let can_edit = matches!(my_role, proto::ChannelRole::Admin | proto::ChannelRole::Member | proto::ChannelRole::Talker);
let capability = if can_edit { Capability::ReadWrite } else { Capability::ReadOnly };
client.join_project(project_id, capability).await?; Type guard
fn can_edit_projects(role: proto::ChannelRole) -> bool {
use proto::ChannelRole::*;
matches!(role, Admin | Member | Talker)
} Try / catch
match client.join_project(project_id, true).await {
Ok(joined) => Ok(joined),
Err(err) if err.to_string().contains("not authorized to edit projects") => {
client.join_project(project_id, false).await // read-only fallback
}
Err(err) => Err(err),
} Prevention
- Read your room role from the room state and choose the join capability accordingly
- Default guests to read-only joins; escalate to read-write only after a role promotion
- Listen for role-change events and re-evaluate capabilities before reconnect joins
When it happens
Trigger: JoinProject with read_write=true from a user whose room role is Guest or Talker (e.g. invited into a room as a guest); joining a project shared in a room the user was banned from (role defaults to Banned); channel rooms that assign guest roles to non-members.
Common situations: A guest invited to a call tries to edit files in the shared project; permission model changed between client and server versions; admin demoted a user to Talker mid-session and the client reconnects with read-write.
Related errors
- not authorized to read projects
- user is not a channel admin or channel does not exist
- user is not a channel member or channel does not exist
- user is not a channel participant or channel does not exist
- guests cannot share projects
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/1457eec67c152a04.
Report an issue: GitHub.