{"record":{"id":"8d98681d143066bb","repo":"siyuan-note/siyuan","slug":"template-packages-cannot-be-renamed-or-moved","errorCode":null,"errorMessage":"template packages cannot be renamed or moved","messagePattern":"template packages cannot be renamed or moved","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_manage.go","lineNumber":294,"sourceCode":"\t}\n\tswitch request.Action {\n\tcase \"write\":\n\t\tif info == nil {\n\t\t\tif err = validateNewTemplateName(request.Path); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tif len(request.Content) > maxTemplateSourceSize {\n\t\t\treturn nil, errors.New(\"template source is too large\")\n\t\t}\n\t\tif info != nil && info.IsDir() {\n\t\t\treturn nil, errors.New(\"cannot write a template directory\")\n\t\t}\n\t\terr = writeTemplateSource(root, request.Path, request.Content, info == nil)\n\t\treturn map[string]string{\"revision\": fmt.Sprintf(\"%x\", sha256.Sum256([]byte(request.Content)))}, err\n\tcase \"move\":\n\t\tif info.IsDir() && isManagedTemplatePackage(root, request.Path) {\n\t\t\treturn nil, errors.New(\"template packages cannot be renamed or moved\")\n\t\t}\n\t\tif err = checkTemplateFilePath(root, request.Target); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err = validateNewTemplateName(request.Target); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !info.IsDir() && !strings.EqualFold(path.Ext(request.Target), \".md\") {\n\t\t\treturn nil, errors.New(\"template source must use the .md extension\")\n\t\t}\n\t\tif _, err = root.Stat(request.Target); !errors.Is(err, os.ErrNotExist) {\n\t\t\treturn nil, errors.New(\"template destination already exists or is inaccessible\")\n\t\t}\n\t\treturn nil, root.Rename(request.Path, request.Target)\n\tcase \"remove\":\n\t\t// 将整个目录连同包资源移入隐藏恢复目录，保留误删后的恢复材料。\n\t\ttrash := \".trash/\" + ast.NewNodeID()\n\t\tif err = root.MkdirAll(trash, 0700); err != nil {","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template_manage.go#L276-L312","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Leave marketplace-installed template packages in place; rename only plain .md templates or unmanaged directories","If reorganization is required, uninstall the package via the marketplace and reinstall under the desired identity","Exclude directories containing template.json from bulk move/rename scripts (check the listing's isPackage flag returned by action=\"list\")"],"exampleFix":"// before\n{ \"action\": \"move\", \"path\": \"fancy-pack\", \"target\": \"renamed-pack\" }   // fancy-pack/template.json exists\n// after: skip packages\nif (!entry.isPackage) { move({ path: entry.path, target: entry.path + \".bak\" }) }","handlingStrategy":"validation","validationCode":"const entry = (await manageTemplateFiles({ action: 'list' })).find(e => e.path === src);\nif (entry?.isPackage) {\n  throw new Error(`'${src}' is a managed template package and cannot be moved or renamed`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await manageTemplateFiles({ action: 'move', path: src, target: dst });\n} catch (e) {\n  if (String(e.message).includes('packages cannot be renamed or moved')) {\n    // skip this entry in bulk operations; manage packages via the marketplace instead\n  }\n}","preventionTips":["Filter out entries with isPackage=true from bulk rename/move scripts","Treat directories containing template.json as read-only identity (marketplace-managed)","Reinstall packages under a new identity instead of renaming them in place"],"tags":["template","package","unsupported-operation","move"],"backgroundTag":"unsupported-operation","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}