{"record":{"id":"7a6fbd45c046e3c2","repo":"charmbracelet/crush","slug":"read-builtin-skill-q-w","errorCode":null,"errorMessage":"read builtin skill %q: %w","messagePattern":"read builtin skill %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skills/catalog.go","lineNumber":94,"sourceCode":"func ReadContent(active []*Skill, skillPaths []string, workingDir string, skillID string) ([]byte, SkillReadResult, error) {\n\tskill, err := FindEffective(active, skillID)\n\tif err != nil {\n\t\treturn nil, SkillReadResult{}, err\n\t}\n\n\t_, source := skillLabel(skillPaths, workingDir, skill)\n\tresult := SkillReadResult{\n\t\tName:        skill.Name,\n\t\tDescription: skill.Description,\n\t\tSource:      source,\n\t\tBuiltin:     skill.Builtin,\n\t}\n\n\tif skill.Builtin {\n\t\tembeddedPath := \"builtin/\" + strings.TrimPrefix(skill.SkillFilePath, BuiltinPrefix)\n\t\tcontent, err := BuiltinFS().ReadFile(embeddedPath)\n\t\tif err != nil {\n\t\t\treturn nil, SkillReadResult{}, fmt.Errorf(\"read builtin skill %q: %w\", skillID, err)\n\t\t}\n\t\treturn content, result, nil\n\t}\n\n\tcontent, err := os.ReadFile(skill.SkillFilePath)\n\tif err != nil {\n\t\treturn nil, SkillReadResult{}, fmt.Errorf(\"read skill %q: %w\", skillID, err)\n\t}\n\treturn content, result, nil\n}\n\nfunc skillLabel(skillPaths []string, workingDir string, skill *Skill) (string, SourceType) {\n\tif skill.Builtin {\n\t\treturn string(SourceSystem) + \":\" + skill.Name, SourceSystem\n\t}\n\n\tcleanFile := filepath.Clean(skill.SkillFilePath)\n\tfor _, base := range skillPaths {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/skills/catalog.go#L76-L112","documentation":"ReadContent, when handling a builtin (embedded) skill, reads the SKILL.md content from the embedded filesystem (BuiltinFS) under the 'builtin/' prefix. This error wraps any failure of that embedded read — effectively meaning the skill is marked Builtin but its file is missing from the embedded FS or the path derived from SkillFilePath is wrong. The underlying fs error is wrapped with %w for errors.Is/As inspection.","triggerScenarios":"Calling skills.ReadContent with a skill whose SkillFilePath starts with BuiltinPrefix and is flagged Builtin, but BuiltinFS().ReadFile(\"builtin/<trimmed path>\") fails — i.e. the embedded asset was not compiled in or the trimmed path does not match the embedded layout.","commonSituations":"A builtin skill directory was renamed/removed in a newer build while cached state still references it; embed directives updated so a skill file is no longer included; custom builds excluding the builtin embed.","solutions":["Rebuild the binary so embedded builtin skill assets match the current source (go build .)","Verify the file exists under internal/skills/builtin/ and that the embed pattern includes it","Check that SkillFilePath minus BuiltinPrefix resolves to the correct path inside the embedded FS","Update cached skill discovery state so it no longer references the removed builtin skill"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"content, result, err := skills.ReadContent(active, paths, dir, skillID)\nif err != nil {\n    var perr error\n    if errors.As(err, &perr) && skill.Builtin {\n        log.Warn(\"builtin skill missing from embedded FS\", \"id\", skillID)\n        return nil, result // degrade gracefully instead of failing the request\n    }\n    return err\n}","preventionTips":["Rebuild the binary after pulling changes so embedded assets stay in sync","Keep builtin skills under internal/skills/builtin/ with embed patterns unchanged","Treat builtin-read errors as build/deploy issues, not user errors","Add a startup smoke test that reads every builtin skill ID"],"tags":["skills","embedded-fs","io","builtin"],"backgroundTag":"embedded-file-read-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}