{"record":{"id":"4879c4635f2bbb3c","repo":"plandex-ai/plandex","slug":"the-ai-model-s-s-stopped-streaming-with-error","errorCode":null,"errorMessage":"The AI model (%s/%s) stopped streaming with error code %d: %s","messagePattern":"The AI model \\((.+?)/(.+?)\\) stopped streaming with error code (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/model/plan/tell_stream_main.go","lineNumber":169,"sourceCode":"\n\t\t\t// log.Println(\"tell stream main: received stream response\", spew.Sdump(response))\n\n\t\t\tif response.ID != \"\" && state.generationId == \"\" {\n\t\t\t\tstate.generationId = response.ID\n\t\t\t}\n\n\t\t\tif state.firstTokenAt.IsZero() {\n\t\t\t\tstate.firstTokenAt = time.Now()\n\t\t\t}\n\n\t\t\tif response.Error != nil {\n\t\t\t\tlog.Println(\"listenStream - stream finished with error\", spew.Sdump(response.Error))\n\n\t\t\t\tbaseModelConfig := state.fallbackRes.BaseModelConfig\n\t\t\t\tmodelErr := model.ClassifyModelError(response.Error.Code, response.Error.Message, nil, baseModelConfig.HasClaudeMaxAuth)\n\n\t\t\t\tres := state.onError(onErrorParams{\n\t\t\t\t\tstreamErr: fmt.Errorf(\"The AI model (%s/%s) stopped streaming with error code %d: %s\", modelProvider, modelName, response.Error.Code, response.Error.Message),\n\t\t\t\t\tstoreDesc: true,\n\t\t\t\t\tcanRetry:  active.CurrentReplyContent == \"\",\n\t\t\t\t\tmodelErr:  &modelErr,\n\t\t\t\t})\n\t\t\t\tif res.shouldReturn {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif res.shouldContinueMainLoop {\n\t\t\t\t\tcontinue mainLoop\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(response.Choices) == 0 {\n\t\t\t\tif response.Usage != nil {\n\t\t\t\t\tstate.handleUsageChunk(response.Usage)\n\t\t\t\t\treturn\n\t\t\t\t}\n","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/tell_stream_main.go#L151-L187","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Retry the request if canRetry was true (no partial content streamed) — resume the tell request from scratch.","Verify the modelProvider/modelName configuration maps to a valid, currently-available model.","Check provider status page / network egress and API key validity, then re-run.","If it recurs on the same prompt, reduce context (trim conversation/files) or switch to a larger-context model."],"exampleFix":"// before: retrying blindly with same oversized context\nstate.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 == \"\"})\n// after: special-case context-length codes to trim context before retry\nif isContextLengthError(response.Error.Code) {\n    active.TrimContextForRetry()\n}\nstate.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})","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["ai-provider","streaming","network","retry"],"backgroundTag":"llm-stream-error","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}