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
After reading the body, LLMAuto checks the HTTP status and rejects anything outside 200–299, embedding status, Content-Type, and a truncated body preview. The upstream LLM service answered, but with an HTTP-level failure (auth, rate limit, bad request, server error).
Source
Thrown at server/service/system/auto_code_llm.go:45
http.MethodPost,
nil,
nil,
llm,
)
if err != nil {
return nil, fmt.Errorf("调用上游大模型服务失败: %w", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, fmt.Errorf("读取大模型响应失败: %w", err)
}
bodyPreview := previewResponseBody(body)
contentType := res.Header.Get("Content-Type")
if res.StatusCode < 200 || res.StatusCode >= 300 {
return nil, fmt.Errorf("上游大模型服务返回非 2xx: status=%d content-type=%s body=%s", res.StatusCode, contentType, bodyPreview)
}
var resStruct commonResp.Response
if err = json.Unmarshal(body, &resStruct); err != nil {
return nil, fmt.Errorf("解析大模型响应失败: status=%d content-type=%s body=%s err=%w", res.StatusCode, contentType, bodyPreview, err)
}
if resStruct.Code != commonResp.SUCCESS {
return nil, fmt.Errorf("大模型服务返回业务错误: code=%d msg=%s body=%s", resStruct.Code, resStruct.Msg, bodyPreview)
}
return resStruct.Data, nil
}
func (s *AutoCodeService) LLMAutoStream(ctx context.Context, llm common.JSONMap) (*http.Response, error) {
path, err := buildLLMAutoPath(llm)
if err != nil {
return nil, errView on GitHub (pinned to 3136500ef3)
Solutions
- Read the status and body preview in the error to identify the upstream cause (401→key, 429→quota, 400→payload)
- Fix the API key / model name / request payload in the llm config accordingly
- For 429, add backoff/retry respecting the provider's rate limits
- For 5xx, retry later or switch to a fallback provider/region
Example fix
// before: only generic wrap upstream, no status inspection
if err != nil { return nil, err }
// after: inspect status before treating response as success
if res.StatusCode == http.StatusUnauthorized {
return nil, fmt.Errorf("LLM 鉴权失败,请检查 API Key")
}
if res.StatusCode >= 500 {
return nil, fmt.Errorf("LLM 服务端错误,可稍后重试: status=%d", res.StatusCode)
} Defensive patterns
Strategy: validation
Validate before calling
if res.StatusCode < 200 || res.StatusCode >= 300 {
return fmt.Errorf("上游返回非 2xx: status=%d body=%s", res.StatusCode, previewResponseBody(body))
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "status=429") {
// backoff and retry respecting rate limit
} else if strings.Contains(err.Error(), "status=401") {
// refresh API key / surface auth config error to operator
}
return err
} Prevention
- Keep API keys and model names in validated config; check for emptiness before calling
- Monitor provider quota to anticipate 429s
- Pin model identifiers and update them when the provider changes versions
- Log status + body preview on failure for fast triage
When it happens
Trigger: Calling LLMAuto when the upstream returns 4xx/5xx — e.g. 401 for a bad/expired API key, 429 rate limit, 400 for an invalid model name or malformed payload, 502/503 for upstream outages.
Common situations: Rotated or unset API keys, exhausted provider quota, wrong model identifier after a provider version change, payload fields not accepted by the provider, provider regional outage.
Related errors
- LLM request failed
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s body=%s
- 调用上游大模型失败: %w
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/c46eead0b5fd94e6.
Report an issue: GitHub.