{"record":{"id":"1eb7789b3836611d","repo":"siyuan-note/siyuan","slug":"skill-md-frontmatter-missing-name-field","errorCode":null,"errorMessage":"SKILL.md frontmatter missing 'name' field","messagePattern":"SKILL\\.md frontmatter missing 'name' field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/skill.go","lineNumber":553,"sourceCode":"\t\tdesc := fm[\"description\"]\n\t\tif desc == \"\" {\n\t\t\tdesc = firstLine(body)\n\t\t}\n\t\tresult.Descriptions = append(result.Descriptions, desc)\n\t}\n\tif len(result.Names) == 0 {\n\t\treturn nil, errors.New(\"no valid skill installed\")\n\t}\n\treturn result, nil\n}\n\n// installFromSingleSkillMD 把单个 SKILL.md 文本内容落地为一个 skill\nfunc installFromSingleSkillMD(data []byte) (*InstallSkillResult, error) {\n\tcontent := string(data)\n\tfm, body := parseSkillFrontmatter(content)\n\tname := fm[\"name\"]\n\tif name == \"\" {\n\t\treturn nil, errors.New(\"SKILL.md frontmatter missing 'name' field\")\n\t}\n\tif err := validateSkillName(name); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := SaveSkill(name, content); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &InstallSkillResult{\n\t\tNames:        []string{name},\n\t\tDescriptions: []string{firstLine(body)},\n\t}, nil\n}\n","sourceCodeStart":535,"sourceCodeEnd":566,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/skill.go#L535-L566","documentation":"Thrown by installFromSingleSkillMD when a text/plain SKILL.md payload's parsed frontmatter contains no 'name' key. Unlike the zip path, the single-file installer has no directory name to fall back on, so the name field is mandatory.","triggerScenarios":"Installing a raw SKILL.md URL whose frontmatter omits 'name'; the frontmatter is malformed (missing '---' delimiters, bad key:value syntax); the file has no frontmatter at all.","commonSituations":"Author forgot the name field; frontmatter uses a different delimiter or indentation the parser does not recognize; the URL actually returns an HTML wrapper page that happens to start with '---'.","solutions":["Add 'name: my-skill' to the SKILL.md frontmatter between the '---' delimiters.","Ensure the frontmatter block is well-formed: opening '---', 'name: value' lines, closing '---'.","Confirm the URL serves the raw markdown, not a rendered HTML page (use raw.githubusercontent.com)."],"exampleFix":"// before\n---\ndescription: does a thing\n---\n# My Skill\n...\n\n// after\n---\nname: my-skill\ndescription: does a thing\n---\n# My Skill\n...","handlingStrategy":"validation","validationCode":"// verify the raw SKILL.md declares a name before installing\nresp, _ := http.Get(rawSkillMDURL)\nb, _ := io.ReadAll(resp.Body)\nfm, _ := parseFrontmatter(string(b))\nif fm[\"name\"] == \"\" {\n    return errors.New(\"SKILL.md must declare a 'name' frontmatter field\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always start a single-file SKILL.md with frontmatter containing 'name: <skill>'.","Use raw.githubusercontent.com links so the payload is markdown, not HTML.","Validate frontmatter delimiters and key syntax before publishing."],"tags":["skill-management","manifest","frontmatter"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}