zed-industries/zed · error

Maximum subagent depth ({}) reached

Error message

Maximum subagent depth ({}) reached

What it means

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.

Source

Thrown at crates/agent/src/agent.rs:3054

    thread: WeakEntity<Thread>,
    acp_thread: WeakEntity<AcpThread>,
}

impl NativeThreadEnvironment {
    pub(crate) fn create_subagent_thread(
        &self,
        label: String,
        cx: &mut App,
    ) -> Result<Rc<dyn SubagentHandle>> {
        let Some(parent_thread_entity) = self.thread.upgrade() else {
            anyhow::bail!("Parent thread no longer exists".to_string());
        };
        let parent_thread = parent_thread_entity.read(cx);
        let current_depth = parent_thread.depth();
        let parent_session_id = parent_thread.id().clone();

        if current_depth >= MAX_SUBAGENT_DEPTH {
            return Err(anyhow!(
                "Maximum subagent depth ({}) reached",
                MAX_SUBAGENT_DEPTH
            ));
        }

        let subagent_thread: Entity<Thread> = cx.new(|cx| {
            let mut thread = Thread::new_subagent(&parent_thread_entity, cx);
            thread.set_title(label.into(), cx);
            thread
        });

        let session_id = subagent_thread.read(cx).id().clone();

        let acp_thread = self
            .agent
            .update(cx, |agent, cx| -> Result<Entity<AcpThread>> {
                let project_id = agent
                    .sessions

View on GitHub (pinned to bc538def45)

Solutions

  1. Rewrite the parent prompt so only top-level threads spawn subagents and subagents do the work inline.
  2. Check thread.depth() against MAX_SUBAGENT_DEPTH before attempting a spawn and fall back to direct execution.
  3. If nesting is truly required, raise MAX_SUBAGENT_DEPTH in crates/agent/src/thread.rs and rebuild — it is a compile-time constant.

Example fix

// before
let subagent = env.create_subagent_thread(label, cx)?; // fails at depth 1

// after
if (thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize {
    let subagent = env.create_subagent_thread(label, cx)?;
} else {
    // execute inline; subagents cannot nest
}
Defensive patterns

Strategy: validation

Validate before calling

use agent::thread::MAX_SUBAGENT_DEPTH;
if (parent_thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize {
    let handle = env.create_subagent_thread(label, cx)?;
} else {
    // depth limit reached: do the work inline
}

Type guard

fn can_spawn_subagent(thread: &Thread) -> bool {
    (thread.depth() as usize) < MAX_SUBAGENT_DEPTH as usize
}

Prevention

When it happens

Trigger: 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.

Common situations: Prompts that tell agents to recursively decompose work; prompt templates ported from setups that assumed deeper nesting; agents spawning helpers for long tasks.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/067bc1f6288a345d. Report an issue: GitHub.