zed-industries/zed · error · Error::Internal

not a collaborator on this project

Error message

not a collaborator on this project

What it means

Thrown by leave_project when the DELETE of the project_collaborator row matching (project_id, connection.id, connection.owner_id) affects zero rows. The server can only remove a collaborator entry that was created by join_project for that exact connection on that exact server, so this error means the calling connection was never a collaborator or already left.

Source

Thrown at crates/collab/src/db/queries/projects.rs:1025

        &self,
        project_id: ProjectId,
        connection: ConnectionId,
    ) -> Result<TransactionGuard<(Option<proto::Room>, LeftProject)>> {
        self.project_transaction(project_id, |tx| async move {
            let result = project_collaborator::Entity::delete_many()
                .filter(
                    Condition::all()
                        .add(project_collaborator::Column::ProjectId.eq(project_id))
                        .add(project_collaborator::Column::ConnectionId.eq(connection.id as i32))
                        .add(
                            project_collaborator::Column::ConnectionServerId
                                .eq(connection.owner_id as i32),
                        ),
                )
                .exec(&*tx)
                .await?;
            if result.rows_affected == 0 {
                Err(anyhow!("not a collaborator on this project"))?;
            }

            let project = project::Entity::find_by_id(project_id)
                .one(&*tx)
                .await?
                .context("no such project")?;
            let collaborators = project
                .find_related(project_collaborator::Entity)
                .all(&*tx)
                .await?;
            let connection_ids: Vec<ConnectionId> = collaborators
                .into_iter()
                .map(|collaborator| collaborator.connection())
                .collect();

            follower::Entity::delete_many()
                .filter(
                    Condition::any()

View on GitHub (pinned to bc538def45)

Solutions

  1. Make leave idempotent on the client: track joined state per connection and only call LeaveProject once per successful join
  2. Ensure the same connection that issued JoinProject issues LeaveProject (do not share join state across connections)
  3. Treat this error as benign in cleanup/teardown code: log it and continue shutting down

Example fix

// before
self.client.leave_project(project_id).await?;

// after (idempotent teardown)
if self.joined_projects.remove(&project_id).is_some() {
    if let Err(err) = self.client.leave_project(project_id).await {
        if err.to_string().contains("not a collaborator") {
            log::debug!("already left project {project_id}");
        } else {
            return Err(err);
        }
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Track joins per connection; only leave what this connection joined.
if self.joined_projects.remove(&project_id).is_none() {
    log::debug!("skip leave_project({project_id}): not joined on this connection");
    return Ok(());
}
client.leave_project(project_id).await?;

Try / catch

match client.leave_project(project_id).await {
    Ok(_) => {}
    Err(err) if err.to_string().contains("not a collaborator") => {
        // already left / never joined from this connection; benign
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling LeaveProject twice on the same connection (second call finds no row); calling leave from a different connection than the one that joined (e.g. another window/device); joining failed earlier and the client proceeds to leave anyway; the project was deleted concurrently.

Common situations: Cleanup paths that run on both window close and app shutdown, firing leave twice; multi-window clients where each window has its own connection; races between leaving and the server dropping the collaborator on connection loss.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/51cc093230c3db93. Report an issue: GitHub.