{"record":{"id":"d75d208f6b6868b4","repo":"zed-industries/zed","slug":"can-t-update-a-project-hosted-by-someone-else","errorCode":null,"errorMessage":"can't update a project hosted by someone else","messagePattern":"can't update a project hosted by someone else","errorType":"validation","errorClass":"Error::Internal","httpStatus":null,"severity":"error","filePath":"crates/collab/src/db/queries/projects.rs","lineNumber":533,"sourceCode":"\n    /// Updates the diagnostic summary for the given connection.\n    pub async fn update_diagnostic_summary(\n        &self,\n        update: &proto::UpdateDiagnosticSummary,\n        connection: ConnectionId,\n    ) -> Result<TransactionGuard<Vec<ConnectionId>>> {\n        let project_id = ProjectId::from_proto(update.project_id);\n        let worktree_id = update.worktree_id as i64;\n        self.project_transaction(project_id, |tx| async move {\n            let summary = update.summary.as_ref().context(\"invalid summary\")?;\n\n            // Ensure the update comes from the host.\n            let project = project::Entity::find_by_id(project_id)\n                .one(&*tx)\n                .await?\n                .context(\"no such project\")?;\n            if project.host_connection()? != connection {\n                return Err(anyhow!(\"can't update a project hosted by someone else\"))?;\n            }\n\n            // Update summary.\n            worktree_diagnostic_summary::Entity::insert(worktree_diagnostic_summary::ActiveModel {\n                project_id: ActiveValue::set(project_id),\n                worktree_id: ActiveValue::set(worktree_id),\n                path: ActiveValue::set(summary.path.clone()),\n                language_server_id: ActiveValue::set(summary.language_server_id as i64),\n                error_count: ActiveValue::set(summary.error_count as i32),\n                warning_count: ActiveValue::set(summary.warning_count as i32),\n            })\n            .on_conflict(\n                OnConflict::columns([\n                    worktree_diagnostic_summary::Column::ProjectId,\n                    worktree_diagnostic_summary::Column::WorktreeId,\n                    worktree_diagnostic_summary::Column::Path,\n                ])\n                .update_columns([","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/collab/src/db/queries/projects.rs#L515-L551","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Only the host connection emits diagnostic summaries\nif project.host_connection_id != connection.id\n    || project.host_connection_server_id != connection.owner_id\n{\n    return Ok(()); // not host: drop the update\n}","typeGuard":null,"tryCatchPattern":"match db.update_worktree_diagnostic_summary(project_id, connection, update).await {\n    Ok(v) => Ok(v),\n    Err(err) if err.to_string().contains(\"hosted by someone else\") => {\n        log::warn!(\"diagnostic update rejected: not the host connection\");\n        Ok(Vec::new())\n    }\n    Err(err) => Err(err),\n}","preventionTips":["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"],"tags":["collab","projects","diagnostics","authorization","connections"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}