flipped-aurora/gin-vue-admin · error
解析下载结果失败: %w
Error message
解析下载结果失败: %w
What it means
The marketplace's 200 response body could not be parsed as the expected JSON shape {"data":{"url":"..."}}. json.Unmarshal failed, meaning the response is not valid JSON or doesn't match the meta struct.
Source
Thrown at server/service/system/sys_skills.go:429
}
defer downloadResp.Body.Close()
if downloadResp.StatusCode != http.StatusOK {
return fmt.Errorf("下载技能失败, HTTP状态码: %d", downloadResp.StatusCode)
}
metaBody, err := io.ReadAll(downloadResp.Body)
if err != nil {
return fmt.Errorf("读取下载结果失败: %w", err)
}
var meta struct {
Data struct {
URL string `json:"url"`
} `json:"data"`
}
if err = json.Unmarshal(metaBody, &meta); err != nil {
return fmt.Errorf("解析下载结果失败: %w", err)
}
realDownloadURL := strings.TrimSpace(meta.Data.URL)
if realDownloadURL == "" {
return errors.New("下载结果缺少 url")
}
zipResp, err := http.Get(realDownloadURL)
if err != nil {
return fmt.Errorf("下载压缩包失败: %w", err)
}
defer zipResp.Body.Close()
if zipResp.StatusCode != http.StatusOK {
return fmt.Errorf("下载压缩包失败, HTTP状态码: %d", zipResp.StatusCode)
}
tmpFile, err := os.CreateTemp("", "gva-skill-*.zip")View on GitHub (pinned to 3136500ef3)
Solutions
- Dump/log the raw metaBody to see what was actually returned
- Verify the marketplace API response contract still nests the URL under data.url
- Check for proxy/WAF HTML responses and exclude them (Content-Type check before Unmarshal)
- Upgrade/redeploy if the server-side struct is stale relative to the marketplace API
Example fix
// add diagnostics before unmarshal
ct := downloadResp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
return fmt.Errorf("unexpected content-type %s: %s", ct, metaBody)
}
if err = json.Unmarshal(metaBody, &meta); err != nil { ... } Defensive patterns
Strategy: type-guard
Validate before calling
resp, err := http.Post(downloadSkillURL, "application/json", body)
if err == nil && !strings.Contains(resp.Header.Get("Content-Type"), "application/json") {
// response is not JSON (HTML error page/captcha) — abort early
} Type guard
func isDownloadMeta(v interface{}) bool {
m, ok := v.(map[string]interface{})
if !ok { return false }
d, ok := m["data"].(map[string]interface{})
if !ok { return false }
url, ok := d["url"].(string)
return ok && url != ""
} Try / catch
if err := DownloadOnlineSkill(ctx, req); err != nil && strings.Contains(err.Error(), "解析下载结果失败") {
// marketplace contract changed or returned HTML; log body and check API version
} Prevention
- Check Content-Type before json.Unmarshal
- Log a bounded sample of unexpected bodies for diagnosis
- Pin/track the marketplace API version in tests
- Detect WAF/captcha HTML responses explicitly
When it happens
Trigger: Calling DownloadOnlineSkill when the marketplace returns HTML (error page via proxy), an empty body, a different envelope (e.g. top-level url instead of data.url), or a captcha/WAF challenge page with 200 status.
Common situations: Marketplace API contract changed after an upgrade; transparent proxies returning HTML; hitting a wrong endpoint variant; CDN serving cached error pages.
Related errors
- 参数错误:generatedFiles 必须是JSON字符串
- params 必须是合法 JSON
- httpHeader 必须是 {"Key":"Value"} 形式的 JSON 对象
- 解析执行计划失败: %v
- 解析执行计划失败: %v 请确保ExecutionPlan格式正确,参考工具描述中的结构体格式要求
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/8ca0dedd4f834540.
Report an issue: GitHub.