{"record":{"id":"8c008c18dec5b2ca","repo":"zed-industries/zed","slug":"parent-thread-no-longer-exists","errorCode":null,"errorMessage":"Parent thread no longer exists","messagePattern":"Parent thread no longer exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent/src/agent.rs","lineNumber":3047,"sourceCode":"            .update(cx, |thread, cx| thread.set_title(title, cx));\n        Task::ready(Ok(()))\n    }\n}\n\npub struct NativeThreadEnvironment {\n    agent: WeakEntity<NativeAgent>,\n    thread: WeakEntity<Thread>,\n    acp_thread: WeakEntity<AcpThread>,\n}\n\nimpl NativeThreadEnvironment {\n    pub(crate) fn create_subagent_thread(\n        &self,\n        label: String,\n        cx: &mut App,\n    ) -> Result<Rc<dyn SubagentHandle>> {\n        let Some(parent_thread_entity) = self.thread.upgrade() else {\n            anyhow::bail!(\"Parent thread no longer exists\".to_string());\n        };\n        let parent_thread = parent_thread_entity.read(cx);\n        let current_depth = parent_thread.depth();\n        let parent_session_id = parent_thread.id().clone();\n\n        if current_depth >= MAX_SUBAGENT_DEPTH {\n            return Err(anyhow!(\n                \"Maximum subagent depth ({}) reached\",\n                MAX_SUBAGENT_DEPTH\n            ));\n        }\n\n        let subagent_thread: Entity<Thread> = cx.new(|cx| {\n            let mut thread = Thread::new_subagent(&parent_thread_entity, cx);\n            thread.set_title(label.into(), cx);\n            thread\n        });\n","sourceCodeStart":3029,"sourceCodeEnd":3065,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent/src/agent.rs#L3029-L3065","documentation":"NativeThreadEnvironment keeps the parent as a WeakEntity<Thread>. If the parent thread entity was dropped before create_subagent_thread runs, the weak upgrade fails and spawning a subagent from it is impossible.","triggerScenarios":"The parent thread is dropped (session closed, all strong handles released) while a tool call was still trying to spawn a subagent; async latency between the spawn request and its execution.","commonSituations":"User closes the panel/thread while the agent is mid-tool-call; tests dropping parent entities eagerly; cancellation races.","solutions":["Cancel pending subagent spawns when the parent session closes.","Keep the parent thread entity alive (store the Entity handle) for the duration of any tool call that may spawn subagents.","Propagate the error to the caller as a cancelled run; do not retry with the same weak handle."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// keep a strong handle alive for the duration of any spawn-capable tool call\nlet parent = environment.parent_thread().upgrade();\nif parent.is_none() {\n    // parent gone: report cancelled instead of spawning\n}","typeGuard":"fn parent_thread_alive(parent: &WeakEntity<Thread>) -> bool {\n    parent.upgrade().is_some()\n}","tryCatchPattern":"match env.create_subagent_thread(label, cx) {\n    Ok(handle) => handle,\n    Err(e) if e.to_string().contains(\"Parent thread no longer exists\") => {\n        // treat as cancelled run; do not retry\n        return Ok(());\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Hold Entity<Thread> (not WeakEntity) across await points where subagents may spawn.","Cancel spawn-capable tool calls when the parent session closes."],"tags":["rust","zed","agent","subagent","lifetime","weak-handle","gpui"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}