flipped-aurora/gin-vue-admin · error
序列化上游请求失败: %w
Error message
序列化上游请求失败: %w
What it means
When body != nil, doUpstream serializes it with json.Marshal; failure is wrapped as '序列化上游请求失败'. json.Marshal only fails on unsupported types (channels, funcs, cyclic structures, invalid numbers), so this almost always signals a bug in the request payload type.
Source
Thrown at server/mcp/http_client.go:181
}
if !strings.HasPrefix(endpoint, "/") {
endpoint = "/" + endpoint
}
baseURL := upstreamBaseURL()
requestURL, err := url.Parse(baseURL + endpoint)
if err != nil {
return nil, fmt.Errorf("构建上游请求地址失败: %w", err)
}
if len(query) > 0 {
requestURL.RawQuery = query.Encode()
}
var reader io.Reader
if body != nil {
payload, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("序列化上游请求失败: %w", err)
}
reader = bytes.NewReader(payload)
}
timeoutCtx, cancel := context.WithTimeout(ctx, requestTimeout())
defer cancel()
req, err := http.NewRequestWithContext(timeoutCtx, method, requestURL.String(), reader)
if err != nil {
return nil, fmt.Errorf("创建上游请求失败: %w", err)
}
req.Header.Set("Accept", "application/json")
req.Header.Set(upstreamAuthHeader, token)
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
// 链路传播:外部 AI → MCP 进程 → GVA 主服务串成同一条 trace
logger.InjectTraceHeaders(timeoutCtx, req)View on GitHub (pinned to 3136500ef3)
Solutions
- Look at the wrapped error — json.Marshal names the offending field/type
- Remove or replace unsupported field types (channel, func, cyclic refs) in the request struct
- Test the payload type with json.Marshal in a unit test
- If NaN/Inf floats are possible, sanitize them before passing body
Example fix
// before
body := map[string]any{"cb": make(chan int)}
resp, err := postUpstream[Result](ctx, "/api/x", nil, body)
// after
body := map[string]any{"id": 123}
resp, err := postUpstream[Result](ctx, "/api/x", nil, body) Defensive patterns
Strategy: validation
Validate before calling
func marshalable(v any) error {
_, err := json.Marshal(v)
return err
} Try / catch
result, err := postUpstream[Data](ctx, "/api/x", nil, body)
if err != nil {
var marshalErr *json.UnsupportedTypeError
if errors.As(err, &marshalErr) || strings.Contains(err.Error(), "序列化上游请求失败") {
// inspect body struct for unsupported field types
}
return err
} Prevention
- Keep request payload types marshal-friendly: no channels, funcs, or cyclic pointers
- Sanitize NaN/Inf floats before building payloads
- Unit-test json.Marshal on every request struct you introduce
- Avoid custom MarshalJSON implementations unless tested
When it happens
Trigger: Request struct contains a channel/func field; cyclic pointer structure; custom MarshalJSON that returns an error; NaN/Inf float values.
Common situations: Passing a context-bearing or cyclic object as body; a recently added field of unsupported type; hand-written MarshalJSON with a bug.
Related errors
- 构建下载请求失败: %w
- 参数错误:generatedFiles 必须是JSON字符串
- params 必须是合法 JSON
- httpHeader 必须是 {"Key":"Value"} 形式的 JSON 对象
- 解析执行计划失败: %v
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/ab9dd4067c27d3b3.
Report an issue: GitHub.