zed-industries/zed · error · MaxOutputTokensError

output token limit reached

Error message

output token limit reached

What it means

MaxOutputTokensError displays as 'output token limit reached' (acp_thread.rs:58). The ACP agent connection reported that the turn stopped at the model's output token ceiling (exceeded_max_output_tokens distinguishes the output limit from the general max-tokens/context case). The thread logs usage, cancels pending same-turn entries, and returns this error so the truncated turn is not treated as success.

Source

Thrown at crates/acp_thread/src/acp_thread.rs:3819

                            let exceeded_max_output_tokens =
                                this.token_usage.as_ref().is_some_and(|u| {
                                    u.max_output_tokens
                                        .is_some_and(|max| u.output_tokens >= max)
                                });

                            if exceeded_max_output_tokens {
                                log::error!(
                                    "Max output tokens reached. Usage: {:?}",
                                    this.token_usage
                                );
                            } else {
                                log::error!("Max tokens reached. Usage: {:?}", this.token_usage);
                            }
                            if is_same_turn {
                                this.cancel_pending_turn_entries(cx);
                            }
                            return Err(anyhow!(MaxOutputTokensError));
                        }

                        let canceled = matches!(r.stop_reason, acp::StopReason::Cancelled);
                        if canceled && is_same_turn {
                            this.cancel_pending_turn_entries(cx);
                        }

                        if !canceled {
                            this.snapshot_completed_plan(cx);
                        }

                        // Handle refusal - distinguish between user prompt and tool call refusals
                        if let acp::StopReason::Refusal = r.stop_reason {
                            this.had_error = true;
                            if let Some((user_msg_ix, _)) = this.last_user_message() {
                                // Check if there's a completed tool call with results after the last user message
                                // This indicates the refusal is in response to tool output, not the user's prompt
                                let has_completed_tool_call_after_user_msg =

View on GitHub (pinned to bc538def45)

Solutions

  1. Raise the output token limit for the model/provider in settings
  2. Split the work: request smaller files or stepwise edits instead of one huge generation
  3. Continue the conversation ('continue'/'go on') to resume from the truncated output rather than restarting
  4. Switch to a model with a larger output window if the task genuinely needs it
Defensive patterns

Strategy: try-catch

Try / catch

match turn_task.await {
    Err(error) if error.is::<MaxOutputTokensError>() => {
        // Turn truncated at the output limit: prompt to continue,
        // do not treat partial output as success.
        show_notice("Output token limit reached — send 'continue' to resume.");
    }
    Err(error) => return Err(error),
    Ok(response) => return Ok(response),
}

Prevention

When it happens

Trigger: A single assistant turn (long file generation, big tool-call sequences, heavy reasoning output) exhausts the max output tokens configured for the model/request; the stop reason maps to the max-token case and the error is returned from the turn task.

Common situations: Provider settings set a low output token limit; asking for one giant artifact instead of incremental edits; models with small output windows; long agentic loops where accumulated generation hits the cap.

Related errors


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