zed-industries/zed · error · Error::Internal
can't update a project hosted by someone else
Error message
can't update a project hosted by someone else
What it means
Thrown by the worktree diagnostic-summary update handler (crates/collab/src/db/queries/projects.rs:533): after loading the project, the sending connection is compared to project.host_connection() and mismatches. Only the host connection may push diagnostic summaries for the shared project's worktrees.
Source
Thrown at crates/collab/src/db/queries/projects.rs:533
/// Updates the diagnostic summary for the given connection.
pub async fn update_diagnostic_summary(
&self,
update: &proto::UpdateDiagnosticSummary,
connection: ConnectionId,
) -> Result<TransactionGuard<Vec<ConnectionId>>> {
let project_id = ProjectId::from_proto(update.project_id);
let worktree_id = update.worktree_id as i64;
self.project_transaction(project_id, |tx| async move {
let summary = update.summary.as_ref().context("invalid summary")?;
// Ensure the update comes from the host.
let project = project::Entity::find_by_id(project_id)
.one(&*tx)
.await?
.context("no such project")?;
if project.host_connection()? != connection {
return Err(anyhow!("can't update a project hosted by someone else"))?;
}
// Update summary.
worktree_diagnostic_summary::Entity::insert(worktree_diagnostic_summary::ActiveModel {
project_id: ActiveValue::set(project_id),
worktree_id: ActiveValue::set(worktree_id),
path: ActiveValue::set(summary.path.clone()),
language_server_id: ActiveValue::set(summary.language_server_id as i64),
error_count: ActiveValue::set(summary.error_count as i32),
warning_count: ActiveValue::set(summary.warning_count as i32),
})
.on_conflict(
OnConflict::columns([
worktree_diagnostic_summary::Column::ProjectId,
worktree_diagnostic_summary::Column::WorktreeId,
worktree_diagnostic_summary::Column::Path,
])
.update_columns([View on GitHub (pinned to bc538def45)
Solutions
- Only the sharing client should send diagnostic-summary updates; clients in participant mode must not forward them
- On reconnect, re-share (or take over hosting) before emitting further updates — a new connection id fails the host check
- Drop queued updates captured under the previous connection instead of replaying them on the new one
Defensive patterns
Strategy: validation
Validate before calling
// Only the host connection emits diagnostic summaries
if project.host_connection_id != connection.id
|| project.host_connection_server_id != connection.owner_id
{
return Ok(()); // not host: drop the update
} Try / catch
match db.update_worktree_diagnostic_summary(project_id, connection, update).await {
Ok(v) => Ok(v),
Err(err) if err.to_string().contains("hosted by someone else") => {
log::warn!("diagnostic update rejected: not the host connection");
Ok(Vec::new())
}
Err(err) => Err(err),
} Prevention
- Never forward diagnostic-summary updates from guest/participant connections
- Drop queued updates captured on a previous connection after a reconnect
- Bind the update stream to the same connection that called share_project
When it happens
Trigger: A guest/collaborator connection in the room (or the host's second connection) sends UpdateWorktreeDiagnosticSummary for a project it did not share; the host reconnected with a new ConnectionId and the old connection emits a late summary update.
Common situations: Guest clients mirroring the host's diagnostic events and wrongly forwarding them; retry queues flushing after a reconnect assigned a new connection id; test harnesses replaying captured updates with an arbitrary connection.
Related errors
- cannot unshare a project hosted by another user
- guests cannot share projects
- not a collaborator on this project
- user is not a channel admin or channel does not exist
- user is not a channel member or channel does not exist
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/d75d208f6b6868b4.
Report an issue: GitHub.