{"record":{"id":"ed9934c2d090f8b0","repo":"siyuan-note/siyuan","slug":"skill-destination-already-exists-or-is-inaccessible","errorCode":null,"errorMessage":"skill destination already exists or is inaccessible","messagePattern":"skill destination already exists or is inaccessible","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/skill_manage.go","lineNumber":419,"sourceCode":"\tswitch request.Action {\n\tcase \"write\":\n\t\tif info != nil && info.IsDir() {\n\t\t\treturn ret, errors.New(\"cannot write a skill directory\")\n\t\t}\n\t\tif err = writeManagedSkillSource(root, request.Path, request.Content, info == nil, request.Revision); err != nil {\n\t\t\treturn ret, err\n\t\t}\n\t\tret.Revision = fmt.Sprintf(\"%x\", sha256.Sum256([]byte(request.Content)))\n\t\treturn ret, nil\n\tcase \"move\":\n\t\tif err = checkManagedSkillPath(root, request.Target); err != nil {\n\t\t\treturn ret, err\n\t\t}\n\t\tif path.Dir(request.Path) != path.Dir(request.Target) {\n\t\t\treturn ret, errors.New(\"skills and text files can only be renamed in the same directory\")\n\t\t}\n\t\tif _, err = root.Lstat(request.Target); !errors.Is(err, os.ErrNotExist) {\n\t\t\treturn ret, errors.New(\"skill destination already exists or is inaccessible\")\n\t\t}\n\t\treturn ret, root.Rename(request.Path, request.Target)\n\tcase \"remove\":\n\t\tif info.IsDir() {\n\t\t\treturn ret, root.RemoveAll(request.Path)\n\t\t}\n\t\treturn ret, root.Remove(request.Path)\n\t}\n\treturn ret, errors.New(\"unsupported skill operation\")\n}\n","sourceCodeStart":401,"sourceCodeEnd":430,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/skill_manage.go#L401-L430","documentation":"The 'move' action refuses to run when the destination path already exists or cannot be stat-ed. Lstat on the target must return os.ErrNotExist; any other outcome (existing file, existing directory, or an access error) aborts the rename to prevent silent overwrites.","triggerScenarios":"Calling ManageSkillFiles with request.Action == \"move\" where root.Lstat(request.Target) returns nil (target exists) or an error other than os.ErrNotExist (e.g. permission denied on the parent dir).","commonSituations":"Renaming a skill to a name that already exists; a stale leftover file at the target; a target directory that is unreadable/unsearchable so Lstat fails.","solutions":["Choose a Target name that does not exist in the source directory","Remove or move away the existing file at the target first","Fix filesystem permissions on the parent directory so Lstat can report ErrNotExist","Verify the target with Lstat before calling move"],"exampleFix":"// before\n{Action: \"move\", Path: \"skills/foo/SKILL.md\", Target: \"skills/foo/README.md\"} // exists\n// after\n{Action: \"move\", Path: \"skills/foo/SKILL.md\", Target: \"skills/foo/SKILL-v2.md\"}","handlingStrategy":"validation","validationCode":"if _, err := root.Lstat(target); !errors.Is(err, os.ErrNotExist) { /* pick another name or clear the target */ }","typeGuard":null,"tryCatchPattern":"if err := ManageSkillFiles(req); err != nil { if strings.Contains(err.Error(), \"destination already exists\") { /* retry with a unique name */ } }","preventionTips":["Always check target existence before rename","Generate unique names (suffix with timestamp/hash) when unsure","Ensure permissions on the parent directory allow Lstat"],"tags":["skill-management","rename","file-already-exists"],"backgroundTag":"file-already-exists","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"}