{"record":{"id":"42aef9e191a5be28","repo":"siyuan-note/siyuan","slug":"unsupported-skill-source-content-type-s-expec","errorCode":null,"errorMessage":"unsupported skill source (content-type: %s); expected a zip archive or a SKILL.md text file","messagePattern":"unsupported skill source \\(content-type: (.+?)\\); expected a zip archive or a SKILL\\.md text file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/skill.go","lineNumber":279,"sourceCode":"\tdata, contentType, err := downloadSkillSource(src)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// 按内容类型或来源判定处理方式\n\tisZip := src.isZip || strings.HasPrefix(contentType, \"application/zip\") ||\n\t\tstrings.HasPrefix(contentType, \"application/x-zip-compressed\")\n\n\tif isZip {\n\t\treturn installFromZip(data)\n\t}\n\n\t// 文本：当作单个 SKILL.md\n\tif strings.HasPrefix(contentType, \"text/\") || strings.HasPrefix(strings.TrimSpace(string(data)), \"---\") {\n\t\treturn installFromSingleSkillMD(data)\n\t}\n\n\treturn nil, fmt.Errorf(\"unsupported skill source (content-type: %s); expected a zip archive or a SKILL.md text file\", contentType)\n}\n\n// normalizeSkillURL 把各种输入归一化为下载源\nfunc normalizeSkillURL(raw string) (normalizedSkillSource, error) {\n\traw = strings.TrimSpace(raw)\n\n\t// 1. 整条 \"npx skills add owner/repo ...\" 命令：提取 owner/repo\n\tif strings.Contains(raw, \"skills add\") || strings.Contains(raw, \"skills@\") {\n\t\tif m := skillsAddPattern.FindStringSubmatch(raw); len(m) == 2 {\n\t\t\treturn codeloadSource(m[1], \"main\"), nil\n\t\t}\n\t}\n\n\t// 2. owner/repo 简写（无 scheme、无点、单个 /）\n\tif !strings.Contains(raw, \"://\") && !strings.Contains(raw, \"//\") && ownerRepoPattern.MatchString(raw) {\n\t\treturn codeloadSource(raw, \"main\"), nil\n\t}\n","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/skill.go#L261-L297","documentation":"Thrown by InstallSkill after a successful download when the content-type is neither a zip (application/zip or application/x-zip-compressed) nor a text file (text/*), AND the body does not start with the '---' frontmatter delimiter. The installer refuses to guess how to handle the payload.","triggerScenarios":"The source returns a content-type like application/octet-stream, application/json, or image/* without a frontmatter marker; a misconfigured server omits a proper content-type; a raw file endpoint serves binary that is not a zip.","commonSituations":"GitHub API endpoints returning application/json instead of a raw file; a release asset that is a .tar.gz (not zip); CDN rewrites content-type; the URL actually points to an HTML error page served as text/html but the body got misread.","solutions":["Point the install at a raw SKILL.md (raw.githubusercontent.com) or a true .zip archive URL.","If serving your own skill, ensure the server emits a correct Content-Type (text/plain or application/zip).","For single-file installs, ensure the file begins with '---' so the frontmatter fallback matches."],"exampleFix":"// before — points to a JSON API endpoint\nutil.InstallSkill(\"https://api.github.com/repos/owner/repo/contents/SKILL.md\")\n\n// after — points to the raw file\nutil.InstallSkill(\"https://raw.githubusercontent.com/owner/repo/main/SKILL.md\")","handlingStrategy":"validation","validationCode":"// prefer sources known to return a supported content-type\nok := strings.Contains(src, \"raw.githubusercontent.com\") || strings.HasSuffix(src, \".zip\") || strings.Contains(src, \"codeload.github.com\")\nif !ok {\n    // warn the user that the endpoint may be unsupported\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer raw.githubusercontent.com for single-file skills and codeload/release zips for collections.","If you host skills yourself, configure the server to emit text/plain or application/zip.","For single-file skills, start the file with '---' so the frontmatter fallback engages."],"tags":["skill-management","network","content-type"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}