{"record":{"id":"62f0546106d9f4ea","repo":"larksuite/cli","slug":"cannot-read-skill-md-w","errorCode":null,"errorMessage":"cannot read SKILL.md: %w","messagePattern":"cannot read SKILL\\.md: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillpolicy/dependencies.go","lineNumber":25,"sourceCode":"\t\"fmt\"\n\t\"io/fs\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\n// skillManifest is the build-integrity metadata frozen when a skill tree is\n// scanned. Runtime content within the owning skill directory remains live, but\n// composition must not be able to change its dependency contract after Resolve.\ntype skillManifest struct {\n\trequiredSkills []string\n}\n\nfunc readSkillManifest(source fs.FS, name string) (skillManifest, error) {\n\tdata, err := fs.ReadFile(source, name+\"/SKILL.md\")\n\tif err != nil {\n\t\treturn skillManifest{}, fmt.Errorf(\"cannot read SKILL.md: %w\", err)\n\t}\n\trequired, err := parseRequiredSkills(name, data)\n\tif err != nil {\n\t\treturn skillManifest{}, err\n\t}\n\treturn skillManifest{requiredSkills: required}, nil\n}\n\n// parseRequiredSkills reads only the structured hard-dependency declaration:\n//\n//\tmetadata:\n//\t  requires:\n//\t    skills: [\"lark-shared\"]\n//\n// Markdown links and prose are intentionally irrelevant. A SKILL.md without\n// YAML frontmatter declares no hard dependencies; malformed frontmatter that\n// purports to be structured metadata fails closed during composition.\nfunc parseRequiredSkills(skillName string, skillMD []byte) ([]string, error) {","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillpolicy/dependencies.go#L7-L43","documentation":"readSkillManifest reads `<skill>/SKILL.md` from the source filesystem to extract the skill's declared dependencies, and wraps any read failure as \"cannot read SKILL.md\". The library requires every composed skill to ship a SKILL.md manifest; a missing or unreadable one makes the skill's dependency contract unverifiable, so composition fails for that skill.","triggerScenarios":"fs.ReadFile(source, name+\"/SKILL.md\") returns an error: the skill directory does not contain SKILL.md, the name is misspelled, the fs.FS is rooted differently than expected, or the file exists but cannot be opened.","commonSituations":"A skill directory added without its SKILL.md; a typo in the skill name passed to the resolver; embedding/embed.FS path mismatch (extra or missing root prefix); a case-sensitivity mismatch (Linux) where the file is named skill.md.","solutions":["Create or restore SKILL.md in the skill directory (with valid frontmatter)","Fix the skill name/path passed to the resolver so it matches the directory containing SKILL.md","Verify the fs.FS root: embed the correct directory so `name+\"/SKILL.md\"` resolves","Check filename case matches SKILL.md exactly on case-sensitive filesystems"],"exampleFix":"// before\nmy-skill/\n  README.md        // no SKILL.md -> \"cannot read SKILL.md: ...\"\n// after\nmy-skill/\n  SKILL.md         // with metadata frontmatter\n  README.md","handlingStrategy":"validation","validationCode":"// check before composing\nif _, err := fs.Stat(source, name+\"/SKILL.md\"); err != nil {\n    return fmt.Errorf(\"skill %q is missing SKILL.md; fix the distribution before resolving\", name)\n}","typeGuard":null,"tryCatchPattern":"manifest, err := readSkillManifest(source, name)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {\n        return fmt.Errorf(\"skill %q has no SKILL.md (fs root %v): %w\", name, pe.Path, err)\n    }\n    return err\n}","preventionTips":["Require SKILL.md in every skill directory via CI or packaging checks","Keep embedded fs.FS roots consistent with skill names","Match filename case exactly (SKILL.md) for cross-platform builds","Add a packaging test that reads every shipped skill's SKILL.md"],"tags":["skillpolicy","filesystem","manifest"],"backgroundTag":"missing-manifest-file","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}