plandex-ai/plandex · error

The AI model (%s/%s) stopped streaming with an error status

Error message

The AI model (%s/%s) stopped streaming with an error status

What it means

Raised in listenStream when a chat-completion chunk arrives with choice.FinishReason == "error" — i.e. the provider signalled failure via a finish-reason field rather than an error object. Unlike error 750 there is no numeric provider code and no modelErr classification, so onError is called with only the stream error; retry eligibility still depends on whether any assistant content was already streamed (canRetry: active.CurrentReplyContent == "").

Source

Thrown at app/server/model/plan/tell_stream_main.go:260

			if processChunkRes.shouldStop {
				log.Println("Model stream reached stop sequence")

				res := handleFinished()
				if res.shouldReturn {
					return
				}
				continue
			}

			if choice.FinishReason != "" {
				log.Println("Model stream finished")
				log.Println("Finish reason: ", choice.FinishReason)

				if choice.FinishReason == "error" {
					log.Println("Model stream finished with error")

					res := state.onError(onErrorParams{
						streamErr: fmt.Errorf("The AI model (%s/%s) stopped streaming with an error status", modelProvider, modelName),
						storeDesc: true,
						canRetry:  active.CurrentReplyContent == "",
					})
					if res.shouldReturn {
						return
					}
					if res.shouldContinueMainLoop {
						continue mainLoop
					}
				}

				res := handleFinished()
				if res.shouldReturn {
					return
				}
				continue
			} else if response.Usage != nil {
				state.handleUsageChunk(response.Usage)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Retry the tell request if no content was streamed yet (canRetry true); the failure is upstream and usually transient.
  2. Check provider status / logs for outages around the timestamp of the stream.
  3. Inspect intermediate chunks in server logs to see if partial output or a provider-side message preceded the error finish reason.
  4. Bypass any local proxy/gateway to rule out stream-mangling middlewares.
  5. If reproducible for one model only, pin a different modelProvider/modelName.
Defensive patterns

Strategy: retry

Validate before calling

// preflight: verify the model is available before streaming
func ensureModelAvailable(provider, model string) error {
    return providerClient.ModelExists(provider, model) // fails fast on deprecated/unknown models
}

Type guard

func isErrorFinishReason(choice Choice) bool {
    return strings.EqualFold(choice.FinishReason, "error")
}

Try / catch

if err != nil {
    if isErrorFinishReason(lastChoice) && active.CurrentReplyContent == "" {
        err = doTellRequest(ctx, ...) // safe to retry: nothing was streamed
    }
}

Prevention

When it happens

Trigger: The streaming response's last choice carries finish_reason "error" — provider aborted the stream, upstream decoding failure, provider-side crash while generating, or a proxy/gateway rewriting a failed response into a normal chunk with an error finish reason.

Common situations: Provider-side generation crash mid-response; a corporate proxy or API gateway mangling the SSE stream; provider deprecating a model so the backend aborts generation; flaky network causing the relay to terminate with a generic error status.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/889b10573581ed23. Report an issue: GitHub.