zed-industries/zed · error

\n\nPartial subagent output (last 3 messages, up to 4096…

Error message

{error:#}\n\nPartial subagent output (last 3 messages, up to 4096 characters each):\n\n{partial_output}

What it means

This error appends the subagent's last 3 partial messages (each truncated to 4096 characters) to the original error when a subagent fails mid-turn. The agent keeps a rolling buffer of the subagent's partial output so failures are debuggable; this variant fires when that buffer is non-empty.

Solutions

  1. Read the appended partial output to see what the subagent was doing when it failed
  2. Reduce the subagent's task scope or max tokens to avoid mid-turn truncation
  3. Check the provider error at the top of the chain (before the 'Partial subagent output' section) for the root cause
  4. Retry the subagent with a smaller or more focused prompt

Example fix

// before
anyhow!("{error:#}\n\nPartial subagent output...{partial_output}")
// after
anyhow!("{error:#}\n\nPartial subagent output (last 3 messages):\n\n{partial_output}").context("subagent failed")
Defensive patterns

Strategy: try-catch

Type guard

fn failure_has_partial_output(error: &str) -> bool { error.contains("Partial subagent output") }

Try / catch

if let Err(error) = result {
    let (root, partial) = error.to_string().split_once("\n\nPartial subagent output")
        .map_or((error.to_string().as_str(), ""), |(r, p)| (r, p));
    eprintln!("root cause: {root}");
}

Prevention

When it happens

Trigger: Subagent thread result is Err, `discard_partial_output` is false, and `thread.subagent_partial_output()` returns a non-empty string — i.e. the model produced some messages before failing.

Common situations: A subagent fails partway through a long tool-using turn: context window exceeded mid-response, tool schema rejected by provider, or stream dropped after partial output.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/a54ae179578f2e33. Report an issue: GitHub.

Appendix: source

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

                Ok(None) => Err(anyhow!("No response from the agent. You can try messaging again.")),
                Err(error) => Err(error),
            };

            parent_thread
                .update(cx, |parent_thread, cx| {
                    parent_thread.unregister_running_subagent(&subagent_session_id, cx)
                })
                .ok();

            if discard_partial_output {
                result
            } else {
                result.map_err(|error| {
                    let partial_output = thread.read_with(cx, |thread, _| thread.subagent_partial_output());
                    if partial_output.is_empty() {
                        anyhow!("{error:#}")
                    } else {
                        anyhow!("{error:#}\n\nPartial subagent output (last 3 messages, up to 4096 characters each):\n\n{partial_output}")
                    }
                })
            }
        })
    }
}

pub struct AcpTerminalHandle {
    terminal: Entity<acp_thread::Terminal>,
    _drop_tx: Option<oneshot::Sender<()>>,
}

impl TerminalHandle for AcpTerminalHandle {
    fn id(&self, cx: &AsyncApp) -> Result<acp::TerminalId> {
        Ok(self.terminal.read_with(cx, |term, _cx| term.id().clone()))
    }

    fn wait_for_exit(&self, cx: &AsyncApp) -> Result<Shared<Task<acp::TerminalExitStatus>>> {

View on GitHub (pinned to 916fc2b8cb)