{"record":{"id":"8055c74701b7ea06","repo":"zed-industries/zed","slug":"temporary-repository-barrier-canceled","errorCode":null,"errorMessage":"temporary repository barrier canceled","messagePattern":"temporary repository barrier canceled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/agent_ui/src/thread_worktree_archive.rs","lineNumber":469,"sourceCode":"\n    let repo_path_for_find = repo_path.to_path_buf();\n    let repo = temp_project\n        .update(cx, |project, cx| {\n            project\n                .repositories(cx)\n                .values()\n                .find(|repo| {\n                    repo.read(cx).snapshot().work_directory_abs_path.as_ref()\n                        == repo_path_for_find.as_path()\n                })\n                .cloned()\n        })\n        .context(\"failed to resolve temporary repository handle\")?;\n\n    let barrier = repo.update(cx, |repo: &mut Repository, _cx| repo.barrier());\n    barrier\n        .await\n        .map_err(|_| anyhow!(\"temporary repository barrier canceled\"))?;\n    Ok((repo, temp_project))\n}\n\n/// Re-adds the worktree to every affected project after a failed\n/// [`remove_root`].\nasync fn rollback_root(root: &RootPlan, cx: &mut AsyncApp) {\n    for affected in &root.affected_projects {\n        let task = affected.project.update(cx, |project, cx| {\n            project.create_worktree(root.root_path.clone(), true, cx)\n        });\n        task.await.log_err();\n    }\n}\n\n/// Saves the worktree's full git state so it can be restored later.\n///\n/// This creates two detached commits (via [`create_archive_checkpoint`] on\n/// the `GitRepository` trait) that capture the staged and unstaged state","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent_ui/src/thread_worktree_archive.rs#L451-L487","documentation":"After building a temporary project for the restore, the code awaits Repository::barrier() so pending git operations finish before the worktree is mutated. This error means the barrier future was dropped — the producing entity or channel was released during window/project teardown — i.e. the wait was cancelled, not that git failed.","triggerScenarios":"Closing the window or dropping the temporary project/repository while the unarchive flow is still awaiting quiescence; the restore task being cancelled mid-await.","commonSituations":"User quits Zed or closes the window during 'Restoring thread…'; tests dropping the AsyncApp context before the await completes.","solutions":["Re-run the restore after reopening; the operation is restartable and did not indicate a git failure.","In code, treat this specific error as abort and skip rollback logic that assumes a git failure.","Keep restore tasks alive (store or detach them) so teardown does not silently drop them mid-operation."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match repo.update(cx, |repo, _| repo.barrier()).await {\n    Ok(_) => { /* proceed with restore */ }\n    Err(_canceled) => {\n        // teardown aborted the wait: skip git-failure rollback, abort quietly\n    }\n}\n// note: the subsequent .context(\"failed to …\") branch is the real git failure path","preventionTips":["Keep restore tasks alive (store or detach them) until git operations complete.","Warn or defer window close while a restore is in flight.","Make teardown idempotent so a cancelled barrier leaves no half-applied state."],"tags":["zed","git","cancellation","worktree-archive","thread-restore"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}