{"record":{"id":"6bef9726a7261eb0","repo":"siyuan-note/siyuan","slug":"skill-path-is-not-a-regular-file-or-directory","errorCode":null,"errorMessage":"skill path is not a regular file or directory","messagePattern":"skill path is not a regular file or directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/skill_manage.go","lineNumber":116,"sourceCode":"\t}\n\treturn workspace.OpenRoot(\"storage/ai/agent/skills\")\n}\n\nfunc checkManagedSkillPath(root *os.Root, p string) error {\n\tif err := validateManagedSkillPath(p); err != nil {\n\t\treturn err\n\t}\n\tparts := strings.Split(p, \"/\")\n\tfor i := range parts {\n\t\tinfo, err := root.Lstat(strings.Join(parts[:i+1], \"/\"))\n\t\tif errors.Is(err, os.ErrNotExist) && i == len(parts)-1 {\n\t\t\treturn nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif info.Mode()&os.ModeSymlink != 0 || (!info.IsDir() && !info.Mode().IsRegular()) {\n\t\t\treturn errors.New(\"skill path is not a regular file or directory\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc isManagedSkillManifest(p string) bool {\n\treturn strings.Count(p, \"/\") == 1 && strings.EqualFold(path.Base(p), \"SKILL.md\")\n}\n\n// 目录版本包含每个资源的内容哈希，保持大小和修改时间不变的外部编辑也会产生冲突。\nfunc managedSkillRevision(root *os.Root, p string) (string, error) {\n\th := sha256.New()\n\terr := fs.WalkDir(root.FS(), p, func(name string, entry fs.DirEntry, walkErr error) error {\n\t\tif walkErr != nil {\n\t\t\treturn walkErr\n\t\t}\n\t\tinfo, err := entry.Info()\n\t\tif err != nil {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/skill_manage.go#L98-L134","documentation":"checkManagedSkillPath validates each ancestor component of a managed-skill path under data/storage/ai/agent/skills. This error means an existing path component is neither a symlink-free directory nor a regular file (e.g. a symlink, FIFO, device or socket), so skill file operations refuse to touch it. The library enforces this to prevent link redirection and special-file side effects inside the skill storage root.","triggerScenarios":"Any ManageSkillFiles action (list/read/write/create/mkdir/move/remove) whose request.Path, Target, or an intermediate path component resolves to a symlink or special file (non-regular, non-directory) via root.Lstat during checkManagedSkillPath; also re-checked after writeManagedSkillSource writes the temp file, so the target being swapped to a link mid-operation also raises it.","commonSituations":"A user manually created symlinks inside storage/ai/agent/skills to share skills between workspaces; a synced/copied directory contains macOS Finder aliases or Windows junction points; a leftover FIFO or socket from another tool occupies a skill name.","solutions":["Inspect the reported path under data/storage/ai/agent/skills with ls -l (or equivalent) and delete or replace the symlink/special file with a real directory or file","Copy the actual skill content into a real directory instead of linking it","Re-run the skill management operation after the path contains only regular files and directories"],"exampleFix":"// before (shell, in workspace)\nln -s ~/shared-skills/my-skill data/storage/ai/agent/skills/my-skill\n// after\ncp -r ~/shared-skills/my-skill data/storage/ai/agent/skills/my-skill","handlingStrategy":"validation","validationCode":"func pathIsClean(root *os.Root, p string) error {\n  info, err := root.Lstat(p)\n  if err != nil { return err }\n  if info.Mode()&os.ModeSymlink != 0 || (!info.IsDir() && !info.Mode().IsRegular()) {\n    return errors.New(\"symlink or special file at \" + p)\n  }\n  return nil\n}","typeGuard":"func isRegularOrDir(info os.FileInfo) bool {\n  return info.Mode()&os.ModeSymlink == 0 && (info.IsDir() || info.Mode().IsRegular())\n}","tryCatchPattern":"if err := ManageSkillFiles(req); err != nil && strings.Contains(err.Error(), \"not a regular file or directory\") {\n  // surface guidance: remove symlinks/special files from skill storage\n}","preventionTips":["Never symlink into data/storage/ai/agent/skills; copy content instead","Audit skill storage after syncing between machines or platforms for links/junctions","Keep IPC artifacts like FIFOs and sockets out of the workspace data directory"],"tags":["filesystem","symlink","security","skills"],"backgroundTag":"path-traversal-blocked","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}