{"record":{"id":"97253987903676ba","repo":"siyuan-note/siyuan","slug":"exporting-symbolic-links-is-not-supported","errorCode":null,"errorMessage":"exporting symbolic links is not supported","messagePattern":"exporting symbolic links is not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/export.go","lineNumber":863,"sourceCode":"\t}\n\n\texportFilePath = path.Join(\"temp\", \"export\")\n\tif encryptedBoxID != \"\" {\n\t\texportFilePath = path.Join(\"temp\", \"export\", registerManagedEncryptedExport(encryptedBoxID, \"resources\", zipFilePath))\n\t} else {\n\t\texportFilePath = path.Join(exportFilePath, filepath.Base(zipFilePath))\n\t}\n\treturn\n}\n\n// copyExportResource 复制导出资源，目录逐文件处理以避免将加密资源作为普通文件读取。\nfunc copyExportResource(source, destination string) error {\n\tinfo, err := os.Lstat(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif info.Mode()&os.ModeSymlink != 0 {\n\t\treturn errors.New(\"exporting symbolic links is not supported\")\n\t}\n\tif !info.IsDir() {\n\t\treturn copyExportFile(source, destination)\n\t}\n\n\treturn filepath.WalkDir(source, func(current string, entry fs.DirEntry, walkErr error) error {\n\t\tif walkErr != nil {\n\t\t\treturn walkErr\n\t\t}\n\t\tif entry.Type()&os.ModeSymlink != 0 {\n\t\t\treturn errors.New(\"exporting symbolic links is not supported\")\n\t\t}\n\t\trelativePath, relErr := filepath.Rel(source, current)\n\t\tif relErr != nil {\n\t\t\treturn relErr\n\t\t}\n\t\ttarget := filepath.Join(destination, relativePath)\n\t\tif entry.IsDir() {","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/export.go#L845-L881","documentation":"Returned by copyExportResource when os.Lstat on the top-level resource path shows the ModeSymlink bit set. SiYuan refuses to export symlinks because a symlink can point outside the workspace (and outside an encrypted notebook's assets dir), which would leak plaintext paths or escape the workspace sandbox. The check uses Lstat, so the link itself (not its target) is inspected.","triggerScenarios":"ExportResources called with a resource path that is itself a symbolic link. Common on Linux/macOS where users symlink asset folders into the workspace, or where a sync tool replaced a file with a symlink.","commonSituations":"User created a symlink inside the workspace assets folder pointing to an external directory. A cloud-sync client (Dropbox/OneDrive) represented a placeholder file as a symlink. Migrating data via symlinks.","solutions":["Replace the symlink with the actual file or a copy of its target inside the workspace, then export.","Resolve the symlink to its real target and ensure that target is a regular file or directory inside the workspace before exporting.","Avoid storing symlinks inside the SiYuan assets folder — copy real files instead.","If using a sync client, configure it to materialize files rather than leave symlink placeholders."],"exampleFix":"# before — assets/myvideo is a symlink to /mnt/external/clip.mp4\nls -la workspace/data/notebook/assets/myvideo\n# after — replace symlink with the real file (or a copy)\nrm workspace/data/notebook/assets/myvideo\ncp /mnt/external/clip.mp4 workspace/data/notebook/assets/myvideo","handlingStrategy":"validation","validationCode":"// Reject symlinks before calling ExportResources\nfor _, p := range resourcePaths {\n    full := filepath.Join(util.WorkspaceDir, p)\n    if info, err := os.Lstat(full); err == nil && info.Mode()&os.ModeSymlink != 0 {\n        return fmt.Errorf(\"refusing to export symlink: %s\", p)\n    }\n}","typeGuard":"// isRegularOrRealDir reports whether the path is a real file/dir (not a symlink).\nfunc isRegularOrRealDir(p string) bool {\n    info, err := os.Lstat(p)\n    if err != nil {\n        return false\n    }\n    return info.Mode()&os.ModeSymlink == 0\n}","tryCatchPattern":null,"preventionTips":["Do not store symlinks inside the SiYuan assets folder; copy real files.","Resolve symlinks to their targets and ensure targets are regular files inside the workspace.","Configure sync clients to materialize files rather than leave symlink placeholders."],"tags":["filesystem","symlink","security","export","resources"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}