flipped-aurora/gin-vue-admin · warning
构建下载请求失败: %w
Error message
构建下载请求失败: %w
What it means
DownloadOnlineSkill serializes {plugin_id, version} to JSON before POSTing to the skill marketplace. json.Marshal on a map[string]interface{} with string values essentially never fails, so this wrap is a defensive guard; it fires only if a value in the map cannot be marshaled (e.g. a channel, func, or unsupported type injected into the map).
Source
Thrown at server/service/system/sys_skills.go:399
if err := writeConstraint(tool, req.Content); err != nil {
return err
}
}
return nil
}
func (s *SkillsService) DownloadOnlineSkill(_ context.Context, req request.DownloadOnlineSkillReq) error {
skillsDir, err := s.toolSkillsDir(req.Tool)
if err != nil {
return err
}
body, err := json.Marshal(map[string]interface{}{
"plugin_id": req.ID,
"version": req.Version,
})
if err != nil {
return fmt.Errorf("构建下载请求失败: %w", err)
}
downloadReq, err := http.NewRequest(http.MethodPost, "https://plugin.gin-vue-admin.com/api/shopPlugin/downloadSkill", bytes.NewReader(body))
if err != nil {
return fmt.Errorf("构建下载请求失败: %w", err)
}
downloadReq.Header.Set("Content-Type", "application/json")
downloadResp, err := http.DefaultClient.Do(downloadReq)
if err != nil {
return fmt.Errorf("下载技能失败: %w", err)
}
defer downloadResp.Body.Close()
if downloadResp.StatusCode != http.StatusOK {
return fmt.Errorf("下载技能失败, HTTP状态码: %d", downloadResp.StatusCode)
}
View on GitHub (pinned to 3136500ef3)
Solutions
- Check the wrapped %v message for 'unsupported type' to find the offending field
- Keep req.ID and req.Version as plain strings and convert before building the map
- Implement json.Marshaler on any custom type placed into the payload
Example fix
// before
"plugin_id": req.ID, // ID became chan string after a refactor
// after
"plugin_id": fmt.Sprintf("%v", req.ID), // ensure serializable primitives Defensive patterns
Strategy: validation
Validate before calling
payload := map[string]interface{}{"plugin_id": req.ID, "version": req.Version}
if _, err := json.Marshal(payload); err != nil {
// reject before calling the service
} Type guard
func isJSONSerializable(v interface{}) bool { _, err := json.Marshal(v); return err == nil } Try / catch
if err := DownloadOnlineSkill(ctx, req); err != nil {
if strings.Contains(err.Error(), "unsupported type") {
// marshal bug in payload construction, fix the map values
}
} Prevention
- Keep request payload fields as plain primitives (string)
- Add a unit test marshaling the download payload
- Use typed structs instead of map[string]interface{} for request bodies
- Never put func/chan values into JSON payloads
When it happens
Trigger: Practically unreachable with the current hardcoded map of two string fields; would fire only if req.ID or req.Version were changed to an unmarshalable type, or the map construction were modified to include unsupported values.
Common situations: Code changes introducing a non-serializable value (func/chan/custom type without MarshalJSON) into the request map.
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/9ea58f2a5e551622.
Report an issue: GitHub.