{"record":{"id":"f4d70aebedfb13c1","repo":"alibaba/spring-ai-alibaba","slug":"skill-md-not-found-at","errorCode":null,"errorMessage":"SKILL.md not found at: {}","messagePattern":"SKILL\\.md not found at: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/skills/SkillMetadata.java","lineNumber":98,"sourceCode":"\t}\n\n\tpublic String getFullContent() {\n\t\treturn fullContent;\n\t}\n\n\tpublic List<String> getAllowedTools() {\n\t\treturn allowedTools;\n\t}\n\n\tpublic void setAllowedTools(List<String> allowedTools) {\n\t\tthis.allowedTools = allowedTools == null ? List.of() : List.copyOf(allowedTools);\n\t}\n\n\tpublic String loadFullContent() throws IOException {\n\t\tif (fullContent == null) {\n\t\t\tPath skillFile = Path.of(skillPath, \"SKILL.md\");\n\t\t\tif (!Files.exists(skillFile)) {\n\t\t\t\tthrow new IOException(\"SKILL.md not found at: \" + skillFile);\n\t\t\t}\n\n\t\t\tString rawContent = Files.readString(skillFile);\n\t\t\tfullContent = removeFrontmatter(rawContent);\n\t\t}\n\t\treturn fullContent;\n\t}\n\n\tprivate String removeFrontmatter(String content) {\n\t\tif (!content.startsWith(\"---\")) {\n\t\t\treturn content;\n\t\t}\n\n\t\tint endIndex = content.indexOf(\"---\", 3);\n\t\tif (endIndex == -1) {\n\t\t\treturn content;\n\t\t}\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/skills/SkillMetadata.java#L80-L116","documentation":"SkillMetadata.loadFullContent lazily reads SKILL.md from the skill's directory and caches it. If the file does not exist at skillPath/SKILL.md, an IOException is thrown because a skill is defined by its SKILL.md file and cannot be loaded without it.","triggerScenarios":"Calling loadFullContent (directly or via readSkillContent/readSkillContentByPath) when the directory at skillPath lacks a SKILL.md file — wrong path, missing packaging, or path pointing at the file itself instead of its directory.","commonSituations":"Deployed jar missing skill resource directories; skill folder copied without SKILL.md; wrong casing (skill.md) on case-sensitive filesystems; path configured relative to a working directory different from runtime.","solutions":["Verify Files.exists(Path.of(skillPath, \"SKILL.md\")) before loading and fix skillPath to point at the skill directory","Check for case-sensitive filename mismatches (must be exactly SKILL.md)","If packaging resources, ensure SKILL.md is copied into the built artifact (Maven resources include)","Use an absolute path or resolve relative paths against the correct base directory at runtime"],"exampleFix":"// before\nSkillMetadata meta = SkillMetadata.builder().name(\"x\").skillPath(\"skills/x/SKILL.md\")...build();\n// after: point at the directory containing SKILL.md\nSkillMetadata meta = SkillMetadata.builder().name(\"x\").skillPath(\"skills/x\")...build();","handlingStrategy":"validation","validationCode":"Path f = Path.of(skillPath, \"SKILL.md\");\nif (!Files.isRegularFile(f)) throw new IllegalArgumentException(\"Missing SKILL.md at \" + f);","typeGuard":"boolean hasSkillManifest(String skillPath) {\n    return Files.isRegularFile(Path.of(skillPath, \"SKILL.md\"));\n}","tryCatchPattern":"try { content = skill.loadFullContent(); } catch (IOException e) { if (e.getMessage().startsWith(\"SKILL.md not found\")) { content = fallbackContent(skill.getName()); } else throw e; }","preventionTips":["Point skillPath at the directory containing SKILL.md, not the file itself","Verify SKILL.md is included in packaged resources before deployment","Use absolute or classpath-resolved paths; watch out for filename casing on Linux"],"tags":["filesystem","skills","io"],"backgroundTag":"file-not-found","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}