{"record":{"id":"c52c403363089de1","repo":"zed-industries/zed","slug":"worktree-repair-was-canceled","errorCode":null,"errorMessage":"worktree repair was canceled","messagePattern":"worktree repair was canceled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/agent_ui/src/thread_worktree_archive.rs","lineNumber":666,"sourceCode":"    cx: &mut AsyncApp,\n) -> Result<PathBuf> {\n    let (main_repo, _temp_project) =\n        find_or_create_repository(&row.main_repo_path, remote_connection, cx).await?;\n\n    let worktree_path = &row.worktree_path;\n    let app_state = current_app_state(cx).context(\"no app state available\")?;\n    let already_exists = app_state.fs.metadata(worktree_path).await?.is_some();\n\n    let created_new_worktree = if already_exists {\n        let is_git_worktree =\n            resolve_git_worktree_to_main_repo(app_state.fs.as_ref(), worktree_path)\n                .await\n                .is_some();\n\n        if !is_git_worktree {\n            let rx = main_repo.update(cx, |repo, _cx| repo.repair_worktrees());\n            rx.await\n                .map_err(|_| anyhow!(\"worktree repair was canceled\"))?\n                .context(\"failed to repair worktrees\")?;\n        }\n        false\n    } else {\n        // Create worktree at the original commit — the branch still points\n        // here because archival used detached commits.\n        let rx = main_repo.update(cx, |repo, _cx| {\n            repo.create_worktree_detached(worktree_path.clone(), row.original_commit_hash.clone())\n        });\n        rx.await\n            .map_err(|_| anyhow!(\"worktree creation was canceled\"))?\n            .context(\"failed to create worktree\")?;\n        true\n    };\n\n    let (wt_repo, _temp_wt_project) =\n        match find_or_create_repository(worktree_path, remote_connection, cx).await {\n            Ok(result) => result,","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent_ui/src/thread_worktree_archive.rs#L648-L684","documentation":"During restore, when the archived worktree's directory still exists on disk but is not recognized as a git worktree, the code calls repo.repair_worktrees() and awaits its channel. This error means the receiver was dropped — the repository entity or project went away — so the repair was cancelled rather than failing.","triggerScenarios":"Worktree directory exists but its .git link is damaged or the worktree was pruned from the main repo, and the project/repository entity is torn down while repair_worktrees() is still running.","commonSituations":"Closing the window during restore of a machine-pruned worktree; git worktree state damaged by external tooling plus an app teardown race.","solutions":["Retry the restore after reopening the project.","If repair keeps being needed, run 'git worktree repair' in the main repository once, then restore.","In code, distinguish this cancellation from the 'failed to repair worktrees' git error and handle it as an abort."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match repo.update(cx, |repo, _| repo.repair_worktrees()).await {\n    Ok(result) => result.context(\"failed to repair worktrees\")?,\n    Err(_canceled) => {\n        // repair was cancelled by teardown: abort the restore, no git rollback needed\n    }\n}","preventionTips":["Distinguish channel cancellation from the underlying git error and handle it as an abort.","Run 'git worktree repair' proactively when damaged worktrees are detected, outside the restore path.","Prevent closing the window mid-restore."],"tags":["zed","git","cancellation","worktree-repair","thread-restore"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}