siyuan-note/siyuan · error

template packages cannot be renamed or moved

Error message

template packages cannot be renamed or moved

What it means

The move action refuses to rename or relocate a managed template package — a directory containing template.json (detected by isManagedTemplatePackage). Package identity (marketplace updates, search indexing) is tied to the directory name, so moving it would break update tracking. Move is reserved for plain template files and unmanaged folders.

Source

Thrown at kernel/model/template_manage.go:294

	}
	switch request.Action {
	case "write":
		if info == nil {
			if err = validateNewTemplateName(request.Path); err != nil {
				return nil, err
			}
		}
		if len(request.Content) > maxTemplateSourceSize {
			return nil, errors.New("template source is too large")
		}
		if info != nil && info.IsDir() {
			return nil, errors.New("cannot write a template directory")
		}
		err = writeTemplateSource(root, request.Path, request.Content, info == nil)
		return map[string]string{"revision": fmt.Sprintf("%x", sha256.Sum256([]byte(request.Content)))}, err
	case "move":
		if info.IsDir() && isManagedTemplatePackage(root, request.Path) {
			return nil, errors.New("template packages cannot be renamed or moved")
		}
		if err = checkTemplateFilePath(root, request.Target); err != nil {
			return nil, err
		}
		if err = validateNewTemplateName(request.Target); err != nil {
			return nil, err
		}
		if !info.IsDir() && !strings.EqualFold(path.Ext(request.Target), ".md") {
			return nil, errors.New("template source must use the .md extension")
		}
		if _, err = root.Stat(request.Target); !errors.Is(err, os.ErrNotExist) {
			return nil, errors.New("template destination already exists or is inaccessible")
		}
		return nil, root.Rename(request.Path, request.Target)
	case "remove":
		// 将整个目录连同包资源移入隐藏恢复目录,保留误删后的恢复材料。
		trash := ".trash/" + ast.NewNodeID()
		if err = root.MkdirAll(trash, 0700); err != nil {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Leave marketplace-installed template packages in place; rename only plain .md templates or unmanaged directories
  2. If reorganization is required, uninstall the package via the marketplace and reinstall under the desired identity
  3. Exclude directories containing template.json from bulk move/rename scripts (check the listing's isPackage flag returned by action="list")

Example fix

// before
{ "action": "move", "path": "fancy-pack", "target": "renamed-pack" }   // fancy-pack/template.json exists
// after: skip packages
if (!entry.isPackage) { move({ path: entry.path, target: entry.path + ".bak" }) }
Defensive patterns

Strategy: validation

Validate before calling

const entry = (await manageTemplateFiles({ action: 'list' })).find(e => e.path === src);
if (entry?.isPackage) {
  throw new Error(`'${src}' is a managed template package and cannot be moved or renamed`);
}

Try / catch

try {
  await manageTemplateFiles({ action: 'move', path: src, target: dst });
} catch (e) {
  if (String(e.message).includes('packages cannot be renamed or moved')) {
    // skip this entry in bulk operations; manage packages via the marketplace instead
  }
}

Prevention

When it happens

Trigger: ManageTemplateFiles with action="move" where request.Path is a directory containing template.json — e.g. renaming an installed marketplace template package from "fancy-pack" to "my-pack", or moving it into a subfolder.

Common situations: A user tried to reorganize installed marketplace templates via the file API; an automation script bulk-renamed everything under data/templates/ and hit the package directories; confusing a package directory with a plain template folder.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/8d98681d143066bb. Report an issue: GitHub.