{"record":{"id":"5e5ae6d28d3a8e6b","repo":"sipeed/picoclaw","slug":"name-is-required","errorCode":null,"errorMessage":"name is required","messagePattern":"name is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skills/loader.go","lineNumber":43,"sourceCode":"\tMaxDescriptionLength = 1024\n)\n\ntype SkillMetadata struct {\n\tName        string `json:\"name\"`\n\tDescription string `json:\"description\"`\n}\n\ntype SkillInfo struct {\n\tName        string `json:\"name\"`\n\tPath        string `json:\"path\"`\n\tSource      string `json:\"source\"`\n\tDescription string `json:\"description\"`\n}\n\nfunc (info SkillInfo) validate() error {\n\tvar errs error\n\tif info.Name == \"\" {\n\t\terrs = errors.Join(errs, errors.New(\"name is required\"))\n\t} else {\n\t\tif err := ValidateSkillName(info.Name); err != nil {\n\t\t\terrs = errors.Join(errs, err)\n\t\t}\n\t}\n\n\tif info.Description == \"\" {\n\t\terrs = errors.Join(errs, errors.New(\"description is required\"))\n\t} else if len(info.Description) > MaxDescriptionLength {\n\t\terrs = errors.Join(errs, fmt.Errorf(\"description exceeds %d character\", MaxDescriptionLength))\n\t}\n\treturn errs\n}\n\ntype SkillsLoader struct {\n\tworkspace       string\n\tworkspaceSkills string // workspace skills (project-level)\n\tglobalSkills    string // global skills (~/.picoclaw/skills)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/skills/loader.go#L25-L61","documentation":"SkillInfo.validate rejects a skill whose Name is empty. Names are mandatory metadata (SKILL.md frontmatter / registry entries) and, when present, must additionally satisfy ValidateSkillName (pattern ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$, max 64). Empty name and invalid pattern are joined via errors.Join, so both can appear in one error.","triggerScenarios":"Registering or validating a SkillInfo with Name == \"\" — e.g. a SKILL.md whose YAML frontmatter lacks the name field, or a JSON skill payload with an empty/missing name key.","commonSituations":"Hand-written SKILL.md missing frontmatter; frontmatter uses a different key (title: instead of name:); programmatic skill registration passing an uninitialized struct.","solutions":["Add a name field to the SKILL.md frontmatter (or the skill payload), e.g. 'name: my-skill'","Use the directory-name convention: lowercase alphanumerics separated by single hyphens, <= 64 chars","If the name is present but still failing, check the separate pattern error also returned by validate()"],"exampleFix":"# before\n---\ndescription: does a thing\n---\n\n# after\n---\nname: my-skill\ndescription: does a thing\n---","handlingStrategy":"validation","validationCode":"// before loading skills\nfunc validSkillInfo(info skills.SkillInfo) error { return info.ValidateIfExposed() }\n// or inline: reject empty names early\nif info.Name == \"\" { return fmt.Errorf(\"skill %s: name is required\", info.Path) }","typeGuard":null,"tryCatchPattern":"if err := info.Validate(); err != nil { // or the loader's validate path\n    if strings.Contains(err.Error(), \"name is required\") {\n        // fix SKILL.md frontmatter: add name field\n    }\n}","preventionTips":["Always include name and description in SKILL.md frontmatter","Use the directory-name convention for skills so name and folder match","Validate skills in CI with the loader before shipping a workspace"],"tags":["skills","validation","configuration"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}