{"record":{"id":"067bc1f6288a345d","repo":"zed-industries/zed","slug":"maximum-subagent-depth-reached","errorCode":null,"errorMessage":"Maximum subagent depth ({}) reached","messagePattern":"Maximum subagent depth \\((.+?)\\) reached","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent/src/agent.rs","lineNumber":3054,"sourceCode":"    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\n        let session_id = subagent_thread.read(cx).id().clone();\n\n        let acp_thread = self\n            .agent\n            .update(cx, |agent, cx| -> Result<Entity<AcpThread>> {\n                let project_id = agent\n                    .sessions","sourceCodeStart":3036,"sourceCodeEnd":3072,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent/src/agent.rs#L3036-L3072","documentation":"Guard against recursive subagents: MAX_SUBAGENT_DEPTH is 1 (crates/agent/src/thread.rs:77), so a thread that is already a subagent cannot spawn another one. create_subagent_thread checks parent_thread.depth() and fails when current_depth >= MAX_SUBAGENT_DEPTH.","triggerScenarios":"A thread at depth 1 (itself a subagent) calls create_subagent_thread, e.g. a subagent instructed to delegate part of its work to another helper.","commonSituations":"Prompts that tell agents to recursively decompose work; prompt templates ported from setups that assumed deeper nesting; agents spawning helpers for long tasks.","solutions":["Rewrite the parent prompt so only top-level threads spawn subagents and subagents do the work inline.","Check thread.depth() against MAX_SUBAGENT_DEPTH before attempting a spawn and fall back to direct execution.","If nesting is truly required, raise MAX_SUBAGENT_DEPTH in crates/agent/src/thread.rs and rebuild — it is a compile-time constant."],"exampleFix":"// before\nlet subagent = env.create_subagent_thread(label, cx)?; // fails at depth 1\n\n// after\nif (thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize {\n    let subagent = env.create_subagent_thread(label, cx)?;\n} else {\n    // execute inline; subagents cannot nest\n}","handlingStrategy":"validation","validationCode":"use agent::thread::MAX_SUBAGENT_DEPTH;\nif (parent_thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize {\n    let handle = env.create_subagent_thread(label, cx)?;\n} else {\n    // depth limit reached: do the work inline\n}","typeGuard":"fn can_spawn_subagent(thread: &Thread) -> bool {\n    (thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize\n}","tryCatchPattern":null,"preventionTips":["Write prompts so only top-level threads spawn subagents.","Remember MAX_SUBAGENT_DEPTH is 1: subagents cannot nest."],"tags":["rust","zed","agent","subagent","depth-limit","recursion"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}