cli/cli · error
%s is not a directory
Error message
%s is not a directory
What it means
DiscoverLocalSkillsWithOptions stats the path successfully but it is not a directory (e.g. a regular file, socket, or symlink to a file). Discovery needs to walk a directory tree, so it refuses immediately with this explicit message instead of a confusing walk error.
Source
Thrown at internal/skills/discovery/discovery.go:985
)
}
return skills, nil
}
// DiscoverLocalSkillsWithOptions finds skills in a local directory using the
// same conventions as remote discovery, with configurable discovery behavior.
func DiscoverLocalSkillsWithOptions(dir string, opts DiscoverOptions) ([]Skill, error) {
absDir, err := filepath.Abs(dir)
if err != nil {
return nil, fmt.Errorf("could not resolve path: %w", err)
}
info, err := os.Stat(absDir)
if err != nil {
return nil, fmt.Errorf("could not access %s: %w", dir, err)
}
if !info.IsDir() {
return nil, fmt.Errorf("%s is not a directory", dir)
}
if _, err := os.Stat(filepath.Join(absDir, "SKILL.md")); err == nil {
skill, err := localSkillFromDir(absDir)
if err != nil {
return nil, err
}
skill.Path = "."
return []Skill{*skill}, nil
}
var skills []Skill
seen := make(map[string]bool)
err = filepath.Walk(absDir, func(p string, info os.FileInfo, walkErr error) error {
if walkErr != nil {
return walkErr
}View on GitHub (pinned to 0eeec0b92e)
Solutions
- Pass the directory that contains the skills, e.g. the repo root or the skills/ folder, not the SKILL.md file
- If pointing at a single-skill directory, give the directory that holds SKILL.md (its parent), per the documented layouts
- For symlinked paths, confirm the link target is a directory: readlink -f <path>
Example fix
# before
discovery.DiscoverLocalSkills("repo/skills/my-skill/SKILL.md")
# after
discovery.DiscoverLocalSkills("repo") Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
return fmt.Errorf("%s is a file; pass its directory (or the skills root) instead", dir)
} Prevention
- Document that discovery takes directories, never SKILL.md file paths
- Normalize inputs: filepath.Dir for anything ending in SKILL.md before calling
When it happens
Trigger: Passing a path to a SKILL.md file or any regular file instead of its containing directory; passing a symlink that resolves to a file.
Common situations: Users assuming the API takes the manifest file path rather than a directory; shell variables that expand to a file (e.g. $SKILL_PATH set to .../skills/my-skill/SKILL.md); tab-completion landing on the file.
Related errors
- could not access %s: %w
- failed to create ssh command: %w
- failed to create scp command: %w
- failed to migrate as %q pre migration version did not match
- failed to write config after migration: %s
AI-assisted analysis of cli/cli@0eeec0b92e (2026-08-15).
Data as JSON: /api/errors/59f53a40bd909f82.
Report an issue: GitHub.