{"record":{"id":"302a16ab48f4f18e","repo":"siyuan-note/siyuan","slug":"conf-language-14-copy-data-dir-failed-s","errorCode":null,"errorMessage":"Conf.Language(14) (copy data dir failed: %s)","messagePattern":"Conf\\.Language\\(14\\) \\(copy data dir failed: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/export.go","lineNumber":789,"sourceCode":"\nfunc exportData(exportFolder string) (zipPath string, err error) {\n\tFlushTxQueue()\n\tif err = EnsureAllSyncAssets(); err != nil {\n\t\treturn\n\t}\n\n\tlogging.LogInfof(\"exporting data...\")\n\n\tbaseFolderName := \"data-\" + util.CurrentTimeSecondsStr()\n\tif err = os.MkdirAll(exportFolder, 0755); err != nil {\n\t\tlogging.LogErrorf(\"create export temp folder failed: %s\", err)\n\t\treturn\n\t}\n\n\tdata := filepath.Join(util.WorkspaceDir, \"data\")\n\tif err = filelock.Copy(data, exportFolder); err != nil {\n\t\tlogging.LogErrorf(\"copy data dir from [%s] to [%s] failed: %s\", data, baseFolderName, err)\n\t\terr = fmt.Errorf(Conf.Language(14), err.Error())\n\t\treturn\n\t}\n\n\tzipPath = exportFolder + \".zip\"\n\tzip, err := gulu.Zip.Create(zipPath)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"create export data zip [%s] failed: %s\", exportFolder, err)\n\t\treturn\n\t}\n\n\tzipCallback := func(filename string) {\n\t\tutil.PushEndlessProgress(Conf.language(65) + \" \" + fmt.Sprintf(Conf.language(253), filename))\n\t}\n\n\tif err = zip.AddDirectory(baseFolderName, exportFolder, zipCallback); err != nil {\n\t\tlogging.LogErrorf(\"create export data zip [%s] failed: %s\", exportFolder, err)\n\t\treturn\n\t}","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/export.go#L771-L807","documentation":"exportData (called by ExportData) copies the workspace data directory via filelock.Copy; if that copy fails, it wraps the OS error with Conf.Language(14) ('Export failed: %s'). The inner err.Error() carries the underlying reason (permission, file-in-use, IO error).","triggerScenarios":"filelock.Copy(workspace/data, exportFolder) fails during export-data — any OS-level copy error while duplicating the data dir.","commonSituations":"Destination volume full or write-protected; file locked by another process (Windows AV/indexer); permission denied on target folder; source file deleted mid-copy by sync.","solutions":["Read the wrapped %s detail to identify the failing file/reason and fix that specific cause","Check write permissions and free space on the export destination","Close other processes holding workspace files (sync clients, editors, antivirus) and retry"],"exampleFix":"// before\nutil.ExportData() // -> Export failed: ... access is denied\n// after\nchmod/write-enable destination dir, close file locks, then util.ExportData()","handlingStrategy":"try-catch","validationCode":"const targetOk = await canWrite(exportFolder);\nconst freeOk = (await getDiskUsage(exportFolder)).free > 0;\nif (!targetOk || !freeOk) throw new Error(\"Export destination is not writable\");","typeGuard":null,"tryCatchPattern":"try {\n  await exportData();\n} catch (e) {\n  // Conf.Language(14) wraps the OS error in e.msg after 'Export failed: '\n  const inner = String(e.msg).split(\": \").slice(1).join(\": \");\n  logDetailed(inner); // e.g. ENOSPC / EACCES / file-in-use\n}","preventionTips":["Ensure export destination is writable and has free space","Exclude the workspace/data dir from antivirus and sync tools to avoid transient file locks","Read the wrapped inner OS error to pinpoint the failing file before retrying"],"tags":["filesystem","export","copy-failed","io"],"backgroundTag":"file-write-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}