plandex-ai/plandex · error

The AI model (%s/%s) stopped streaming with error code %d: %

Error message

The AI model (%s/%s) stopped streaming with error code %d: %s

What it means

Raised in listenStream when the upstream AI provider's SSE stream terminates with an explicit error payload (response.Error with a numeric code and message). The raw provider error is first passed through ClassifyModelError (which can mark it retryable or auth-related, e.g. Claude max-auth quirks), then wrapped as onErrorParams via state.onError; canRetry is only true when no assistant content has been streamed yet. It surfaces the provider/model name and the provider's own error code so the caller knows which backend failed.

Source

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

			// log.Println("tell stream main: received stream response", spew.Sdump(response))

			if response.ID != "" && state.generationId == "" {
				state.generationId = response.ID
			}

			if state.firstTokenAt.IsZero() {
				state.firstTokenAt = time.Now()
			}

			if response.Error != nil {
				log.Println("listenStream - stream finished with error", spew.Sdump(response.Error))

				baseModelConfig := state.fallbackRes.BaseModelConfig
				modelErr := model.ClassifyModelError(response.Error.Code, response.Error.Message, nil, baseModelConfig.HasClaudeMaxAuth)

				res := state.onError(onErrorParams{
					streamErr: fmt.Errorf("The AI model (%s/%s) stopped streaming with error code %d: %s", modelProvider, modelName, response.Error.Code, response.Error.Message),
					storeDesc: true,
					canRetry:  active.CurrentReplyContent == "",
					modelErr:  &modelErr,
				})
				if res.shouldReturn {
					return
				}
				if res.shouldContinueMainLoop {
					continue mainLoop
				}
			}

			if len(response.Choices) == 0 {
				if response.Usage != nil {
					state.handleUsageChunk(response.Usage)
					return
				}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the provider error code in the message to identify the upstream cause (401/403 => fix credentials, 429 => back off and retry, 400 context length => shrink the prompt).
  2. Retry the request if canRetry was true (no partial content streamed) — resume the tell request from scratch.
  3. Verify the modelProvider/modelName configuration maps to a valid, currently-available model.
  4. Check provider status page / network egress and API key validity, then re-run.
  5. If it recurs on the same prompt, reduce context (trim conversation/files) or switch to a larger-context model.

Example fix

// before: retrying blindly with same oversized context
state.onError(onErrorParams{streamErr: fmt.Errorf("The AI model (%s/%s) stopped streaming with error code %d: %s", modelProvider, modelName, response.Error.Code, response.Error.Message), storeDesc: true, canRetry: active.CurrentReplyContent == ""})
// after: special-case context-length codes to trim context before retry
if isContextLengthError(response.Error.Code) {
    active.TrimContextForRetry()
}
state.onError(onErrorParams{streamErr: fmt.Errorf("The AI model (%s/%s) stopped streaming with error code %d: %s", modelProvider, modelName, response.Error.Code, response.Error.Message), storeDesc: true, canRetry: active.CurrentReplyContent == "", modelErr: &modelErr})
Defensive patterns

Strategy: retry

When it happens

Trigger: The model provider (e.g. OpenAI/Anthropic via modelProvider/modelName) sends an error frame mid-stream: provider outage, invalid or expired API key, rate limit, content-filter rejection, context-length overflow, or a 5xx from the provider relayed as an in-stream error code.

Common situations: Provider API key rotated or quota exhausted mid-session; model name misconfigured after a provider version change; prompt too large for the model's context window; transient provider 529/503 overload during peak hours; Claude max-auth classification changing retry eligibility.

Related errors


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