{"record":{"id":"5581747af828b21e","repo":"charmbracelet/crush","slug":"name-is-required","errorCode":null,"errorMessage":"name is required","messagePattern":"name is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skills/skills.go","lineNumber":122,"sourceCode":"\tdefer latestStatesMu.RUnlock()\n\treturn cloneStates(latestStates)\n}\n\n// SetLatestStates stores the given states in the package-level cache so that\n// GetLatestStates can return them synchronously before the first pubsub event\n// arrives.\nfunc SetLatestStates(states []*SkillState) {\n\tlatestStatesMu.Lock()\n\tlatestStates = cloneStates(states)\n\tlatestStatesMu.Unlock()\n}\n\n// Validate checks if the skill meets spec requirements.\nfunc (s *Skill) Validate() error {\n\tvar errs []error\n\n\tif s.Name == \"\" {\n\t\terrs = append(errs, errors.New(\"name is required\"))\n\t} else {\n\t\tif len(s.Name) > MaxNameLength {\n\t\t\terrs = append(errs, fmt.Errorf(\"name exceeds %d characters\", MaxNameLength))\n\t\t}\n\t\tif !namePattern.MatchString(s.Name) {\n\t\t\terrs = append(errs, errors.New(\"name must be alphanumeric with hyphens, no leading/trailing/consecutive hyphens\"))\n\t\t}\n\t\tif s.Path != \"\" && !strings.EqualFold(filepath.Base(s.Path), s.Name) {\n\t\t\terrs = append(errs, fmt.Errorf(\"name %q must match directory %q\", s.Name, filepath.Base(s.Path)))\n\t\t}\n\t}\n\n\tif s.Description == \"\" {\n\t\terrs = append(errs, errors.New(\"description is required\"))\n\t} else if len(s.Description) > MaxDescriptionLength {\n\t\terrs = append(errs, fmt.Errorf(\"description exceeds %d characters\", MaxDescriptionLength))\n\t}\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/skills/skills.go#L104-L140","documentation":"Skill.Validate enforces the skill spec. It emits this error when the parsed skill's Name field is empty — the frontmatter is missing a `name:` key or it is blank. All validation errors are joined and returned together.","triggerScenarios":"Parsing a SKILL.md whose YAML frontmatter lacks `name:` or has `name: \"\"`, then calling Validate.","commonSituations":"Hand-written skill files missing required frontmatter keys; frontmatter delimiters misplaced so YAML keys are parsed into the body; copying a template and forgetting to fill in the name.","solutions":["Add a `name:` field to the SKILL.md YAML frontmatter","Verify the frontmatter is properly delimited by `---` lines so the name is actually parsed","Re-check that the name also satisfies length and pattern rules once set"],"exampleFix":"// before (SKILL.md frontmatter)\n---\ndescription: Does things\n---\n// after\n---\nname: my-skill\ndescription: Does things\n---","handlingStrategy":"validation","validationCode":"if skill.Name == \"\" {\n\treturn errors.New(\"skill frontmatter must define a name\")\n}","typeGuard":null,"tryCatchPattern":"if err := skill.Validate(); err != nil {\n\treturn fmt.Errorf(\"invalid skill %s: %w\", skill.Path, err)\n}","preventionTips":["Always include name and description in SKILL.md frontmatter","Use a template with required keys filled in","Validate skills as part of CI before packaging"],"tags":["skills","validation","frontmatter"],"backgroundTag":"schema-validation-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}