{"record":{"id":"26c472c8d99de4b8","repo":"larksuite/cli","slug":"s-probing-skill-q-w","errorCode":null,"errorMessage":"%s: probing skill %q: %w","messagePattern":"(.+?): probing skill %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillpolicy/resolver.go","lineNumber":185,"sourceCode":"\tsnapshot := skillTreeSnapshot{source: source, skills: map[string]skillManifest{}}\n\tif source == nil {\n\t\treturn snapshot, nil\n\t}\n\tentries, err := fs.ReadDir(source, \".\")\n\tif err != nil {\n\t\treturn snapshot, fmt.Errorf(\"%s: cannot read root: %w\", label, err)\n\t}\n\tfor _, e := range entries {\n\t\tname := e.Name()\n\t\tif !e.IsDir() {\n\t\t\treturn snapshot, fmt.Errorf(\"%s: %q is not a directory; every %s entry must be a <skill>/ dir\", label, name, label)\n\t\t}\n\t\tif !isSkillName(name) {\n\t\t\treturn snapshot, fmt.Errorf(\"%s: %q is not a valid skill name\", label, name)\n\t\t}\n\t\tok, err := skillExists(source, name)\n\t\tif err != nil {\n\t\t\treturn snapshot, fmt.Errorf(\"%s: probing skill %q: %w\", label, name, err)\n\t\t}\n\t\tif !ok {\n\t\t\treturn snapshot, fmt.Errorf(\"%s: skill %q is missing SKILL.md\", label, name)\n\t\t}\n\t\tmanifest, err := readSkillManifest(source, name)\n\t\tif err != nil {\n\t\t\treturn snapshot, fmt.Errorf(\"%s: skill %q has invalid metadata: %w\", label, name, err)\n\t\t}\n\t\tsnapshot.skills[name] = manifest\n\t}\n\treturn snapshot, nil\n}\n\n// validateSelection rejects allow/remove entries that cannot compose against\n// the already-validated base snapshot.\nfunc validateSelection(lower skillTreeSnapshot, spec *platform.SkillsOverlay) error {\n\tif err := validateSkillNames(\"Allow\", spec.Allow); err != nil {\n\t\treturn err","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillpolicy/resolver.go#L167-L203","documentation":"fs.Stat on <skill>/SKILL.md returned a real error (not fs.ErrNotExist/fs.ErrInvalid) while probing whether a skill directory is well-formed — e.g. a permission or I/O fault. scanSkillTree distinguishes genuine faults from plain absence, which has its own 'missing SKILL.md' message.","triggerScenarios":"ResolveWithReferences scanning a Base/Overlay FS where stat'ing name+\"/SKILL.md\" fails with a non-not-exist error: permission denied, too many open files, network FS outage, or a custom FS whose Stat implementation errors.","commonSituations":"Read-only or restricted permissions on embedded-unpack dirs, disk-backed FS on a failing mount, resource exhaustion (EMFILE) in long-running plugin hosts, or a buggy custom fs.FS Stat.","solutions":["Inspect the wrapped cause after 'probing skill' for the concrete os/fs error","Fix filesystem permissions or the mount serving the skill tree","If a custom fs.FS is used, correct its Stat to return fs.ErrNotExist for absent paths instead of a generic error","Retry after resolving transient I/O/resource conditions (e.g. close leaked file handles)"],"exampleFix":"// before\nfunc (f myFS) Stat(name string) (fs.FileInfo, error) { return nil, errors.New(\"unsupported\") }\n// after\nfunc (f myFS) Stat(name string) (fs.FileInfo, error) {\n\tinfo, err := statImpl(name)\n\tif os.IsNotExist(err) { return nil, fs.ErrNotExist }\n\treturn info, err\n}","handlingStrategy":"retry","validationCode":"if _, err := fs.Stat(skillFS, name+\"/SKILL.md\"); err != nil && !errors.Is(err, fs.ErrNotExist) {\n\treturn fmt.Errorf(\"stat failed for %s: %w\", name, err)\n}","typeGuard":null,"tryCatchPattern":"err := tryResolve()\nif errors.Is(err, fs.ErrPermission) || errors.Is(err, syscall.EMFILE) {\n\t// remediate permissions/handles, then retry once\n}","preventionTips":["Ensure the skill tree is readable by the process user","Return fs.ErrNotExist from custom FS Stat for absent paths","Monitor file-descriptor limits in long-running hosts","Avoid network mounts for embedded skill assets"],"tags":["go","fs","io","stat"],"backgroundTag":"skill-tree-io-failure","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"}