{"record":{"id":"e9cb797da9e71f1a","repo":"siyuan-note/siyuan","slug":"encrypted-resources-are-not-supported","errorCode":null,"errorMessage":"encrypted resources are not supported","messagePattern":"encrypted resources are not supported","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/asset_relink.go","lineNumber":497,"sourceCode":"\treturn \"\", errors.New(\"cannot allocate a replacement history directory\")\n}\n\nfunc validateRelinkStoragePath(abs string) error {\n\treal, err := filepath.EvalSymlinks(abs)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdataRoot, err := filepath.EvalSymlinks(util.DataDir)\n\tif err != nil || !gulu.File.IsSubPath(dataRoot, real) {\n\t\treturn fmt.Errorf(\"resource escapes the data directory: %s\", abs)\n\t}\n\trel, err := filepath.Rel(dataRoot, real)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfirst, _, _ := strings.Cut(filepath.ToSlash(rel), \"/\")\n\tif ast.IsNodeIDPattern(first) && IsEncryptedBox(first) {\n\t\treturn errors.New(\"encrypted resources are not supported\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":479,"sourceCodeEnd":501,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/asset_relink.go#L479-L501","documentation":"Encrypted notebooks (protected by SiYuan's data encryption) are explicitly excluded from asset relinking. If the first path segment of the asset's workspace-relative location matches a notebook ID that is an encrypted box, the operation refuses to proceed rather than risk corrupting or bypassing the encryption envelope semantics.","triggerScenarios":"Running RelinkAssetWithContext/RelinkAssets or a scan where the oldPath (or scanned reference) resolves under a data/<notebookID>/ directory whose ID satisfies ast.IsNodeIDPattern && IsEncryptedBox(first).","commonSituations":"Batch relinking assets across all notebooks when some notebooks use encrypted-notebook mode; automation scripts iterating every notebook folder under data/; migrating content from an encrypted notebook into a normal one while relinking asset paths.","solutions":["Exclude encrypted notebooks from the mapping list and relink only assets under non-encrypted notebooks","Move the asset and its references out of the encrypted notebook into a normal notebook first, then relink","Disable/convert encryption on that notebook only if your recovery plan permits it, then retry"],"exampleFix":"// before\nmappings := allNotebookAssetMappings() // includes encrypted boxes\n// after\nvar filtered []apicontract.AssetRelinkMapping\nfor _, m := range mappings {\n\tbox := firstPathSegment(m.OldPath)\n\tif ast.IsNodeIDPattern(box) && model.IsEncryptedBox(box) {\n\t\tcontinue // skip encrypted notebooks\n\t}\n\tfiltered = append(filtered, m)\n}","handlingStrategy":"validation","validationCode":"func mappingTargetsEncryptedBox(oldPath string) bool {\n\tfirst := firstSegment(filepath.ToSlash(oldPath))\n\treturn ast.IsNodeIDPattern(first) && model.IsEncryptedBox(first)\n}","typeGuard":"if mappingTargetsEncryptedBox(m.OldPath) { skip(m) }","tryCatchPattern":null,"preventionTips":["Skip encrypted notebooks when enumerating notebooks for batch relink","Document that relink is unavailable for encrypted boxes","Keep asset operations in normal notebooks when automation is planned"],"tags":["go","encryption","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}