{"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":857,"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":839,"sourceCodeEnd":870,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/skill.go#L839-L870","documentation":"installFromSingleSkillMD installs a single SKILL.md payload passed directly (not inside a zip). It parses the YAML frontmatter and requires a non-empty 'name' field, since there is no directory name to fall back to. Without it, the skill cannot be identified or stored, so the error is thrown before any file is written.","triggerScenarios":"Passing SKILL.md content to InstallSkill (single-file install path) where the frontmatter lacks 'name' or it is empty; file has no frontmatter block at all.","commonSituations":"Copying a skill body from documentation without its frontmatter; hand-written SKILL.md missing the metadata block; a tool that strips frontmatter during export.","solutions":["Add 'name: <skill-name>' to the YAML frontmatter at the top of the SKILL.md","Confirm the file starts with '---' delimiters so the frontmatter is parsed at all","Ensure the name passes validateSkillName (no spaces/invalid chars)"],"exampleFix":"// before\n# My Skill\nSome content...\n\n// after\n---\nname: my-skill\ndescription: Does something useful\n---\n# My Skill\nSome content...\n","handlingStrategy":"validation","validationCode":"const m = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\nconst hasName = m && /^name:\\s*\\S+/.test(m[1]);\nif (!hasName) throw new Error('SKILL.md frontmatter missing name');","typeGuard":null,"tryCatchPattern":"try {\n  await api.installSkill(mdBytes);\n} catch (e) {\n  if (e.message.includes(\"missing 'name' field\")) {\n    // prepend frontmatter with name before retry\n  }\n}","preventionTips":["Never strip frontmatter when exporting skills","Use a linter/template that enforces name+description frontmatter","Check the file literally starts with '---'"],"tags":["skill-install","frontmatter","missing-field","go"],"backgroundTag":"empty-required-field","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}