flipped-aurora/gin-vue-admin · error
上游大模型流式服务返回非 2xx: status=%d content-type=%s body=%s
Error message
上游大模型流式服务返回非 2xx: status=%d content-type=%s body=%s
What it means
This is the readable-body branch of the same non-2xx check in proxyLLMStream. When the upstream LLM service responds with a status outside 200-299 and its body can be read, the error includes status, Content-Type, and a preview of the body (previewResponseBody). It surfaces the upstream's own error payload (usually JSON with a provider error message) to the caller of LLMAuto.
Source
Thrown at server/api/v1/system/sys_auto_code.go:176
if stream, ok := llm["stream"].(bool); ok && stream {
return true
}
return strings.Contains(strings.ToLower(c.GetHeader("Accept")), "text/event-stream")
}
func (autoApi *AutoCodeApi) proxyLLMStream(c *gin.Context, llm common.JSONMap) error {
res, err := autoCodeService.LLMAutoStream(c.Request.Context(), llm)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode >= 300 {
body, readErr := io.ReadAll(res.Body)
if readErr != nil {
return fmt.Errorf("上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w", res.StatusCode, res.Header.Get("Content-Type"), readErr)
}
return fmt.Errorf("上游大模型流式服务返回非 2xx: status=%d content-type=%s body=%s", res.StatusCode, res.Header.Get("Content-Type"), previewResponseBody(body))
}
flusher, ok := c.Writer.(http.Flusher)
if !ok {
return errors.New("当前响应不支持流式输出")
}
copyLLMStreamHeaders(c.Writer.Header(), res.Header)
if c.Writer.Header().Get("Content-Type") == "" {
c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
}
if c.Writer.Header().Get("Cache-Control") == "" {
c.Writer.Header().Set("Cache-Control", "no-cache")
}
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("X-Accel-Buffering", "no")
c.Status(res.StatusCode)
flusher.Flush()View on GitHub (pinned to 3136500ef3)
Solutions
- Read the body preview in the error message — it normally contains the provider's JSON error (e.g. "invalid_api_key") telling you exactly what to fix.
- Verify the API key/env config for the LLM service and rotate if expired.
- Confirm the model name and API path still exist on the provider (version changes often turn 200 into 404).
- Back off and retry on 429/5xx; add rate limiting on your side to stay under quota.
Example fix
// before
// error: 上游大模型流式服务返回非 2xx: status=401 ... body={"error":"invalid api key"}
LLM_API_KEY=old-expired-key
// after
LLM_API_KEY=sk-current-valid-key # then restart the server Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := client.Do(req)
if err != nil { return err }
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
b, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
return fmt.Errorf("LLM upstream %d: %s", resp.StatusCode, string(b))
} Try / catch
if err := api.proxyLLMStream(c, payload); err != nil {
var apiErr struct{ Error struct{ Message string `json:"message"` } `json:"error"` }
if json.Unmarshal([]byte(extractBody(err.Error())), &apiErr) == nil && apiErr.Error.Message != "" {
c.JSON(502, gin.H{"msg": apiErr.Error.Message})
return
}
c.JSON(502, gin.H{"msg": err.Error()})
} Prevention
- Rotate and validate LLM API keys before deployment
- Pin the model name and check provider version notes on upgrades
- Monitor quota to catch 429 before users do
- Surface the upstream body preview in server logs for fast triage
When it happens
Trigger: LLMAuto -> proxyLLMStream receives 400 (malformed prompt/model name), 401/403 (invalid or expired API key), 404 (wrong model or path), 429 (rate limit), or 5xx (provider outage) with a readable error body from the LLM endpoint.
Common situations: LLM_API_KEY missing/expired, wrong model name after a provider API version change, base URL misconfigured (pointing to a proxy root), free-tier quota exhausted, or provider regional outage producing 5xx JSON error bodies.
Related errors
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
- 调用上游大模型失败: %w
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
- 读取上游流式响应失败: %w
- 调用上游大模型服务失败: %w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/e39f4a9e810746e4.
Report an issue: GitHub.