siyuan-note/siyuan · error

skills and text files can only be renamed in the same…

Error message

skills and text files can only be renamed in the same directory

What it means

The 'move' action only permits renames within a single directory of the skill root: the parent of request.Path must equal the parent of request.Target. This is enforced so managed skill files stay in their designated directory layout; cross-directory relocation is treated as an unsupported operation.

Solutions

  1. Keep Target in the same directory as Path (rename only)
  2. Perform a cross-directory relocation manually: read the file, write it to the new location, then 'remove' the original
  3. Adjust request.Target so its directory component matches request.Path

Example fix

// before
{Action: "move", Path: "skills/foo/SKILL.md", Target: "skills/bar/SKILL.md"}
// after (same-directory rename only)
{Action: "move", Path: "skills/foo/SKILL.md", Target: "skills/foo/SKILL.md.bak"}
Defensive patterns

Strategy: validation

Validate before calling

if path.Dir(srcPath) != path.Dir(targetPath) { /* do read+write+remove manually, or fix target */ }

Try / catch

if err := ManageSkillFiles(req); err != nil { if strings.Contains(err.Error(), "can only be renamed in the same directory") { /* fall back to copy+remove */ } }

Prevention

When it happens

Trigger: Calling ManageSkillFiles with request.Action == "move" where path.Dir(request.Path) != path.Dir(request.Target), e.g. moving skills/foo/SKILL.md to skills/bar/SKILL.md.

Common situations: Developer tries to reorganize skills into subdirectories via move; a user-supplied target in a different folder; concatenating target paths with '..' components that escape the source directory.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/20fe53c853468187. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/skill_manage.go:416

			return ret, errors.New("skill changed; reload it before saving, renaming or deleting")
		}
	}
	switch request.Action {
	case "write":
		if info != nil && info.IsDir() {
			return ret, errors.New("cannot write a skill directory")
		}
		if err = writeManagedSkillSource(root, request.Path, request.Content, info == nil, request.Revision); err != nil {
			return ret, err
		}
		ret.Revision = fmt.Sprintf("%x", sha256.Sum256([]byte(request.Content)))
		return ret, nil
	case "move":
		if err = checkManagedSkillPath(root, request.Target); err != nil {
			return ret, err
		}
		if path.Dir(request.Path) != path.Dir(request.Target) {
			return ret, errors.New("skills and text files can only be renamed in the same directory")
		}
		if _, err = root.Lstat(request.Target); !errors.Is(err, os.ErrNotExist) {
			return ret, errors.New("skill destination already exists or is inaccessible")
		}
		return ret, root.Rename(request.Path, request.Target)
	case "remove":
		if info.IsDir() {
			return ret, root.RemoveAll(request.Path)
		}
		return ret, root.Remove(request.Path)
	}
	return ret, errors.New("unsupported skill operation")
}

View on GitHub (pinned to 9f775e8a12)