siyuan-note/siyuan · critical
copy data failed
Error message
copy data failed
What it means
When importing a whole-data zip (ImportData path within importSY0's flow), the unzipped tree is copied from unzipRootPath into the workspace's data directory with filelock.Copy. If the copy fails, the error is replaced by the generic 'copy data failed' message, hiding the underlying cause in the log. This copy step materializes the imported notebook's documents, assets and .siyuan metadata into the live workspace.
Solutions
- Check the kernel log for the 'copy data dir from [...] to [...] failed' line to identify the exact file and OS error.
- Free disk space (or expand the volume) so the workspace data partition has room for the archive's contents.
- Close other SiYuan instances / exclude the workspace from antivirus indexing, then retry.
- Fix permissions on the workspace data directory so the kernel process can create files there, and retry the import.
Example fix
// before
if err = filelock.Copy(unzipRootPath, targetDir); err != nil {
err = errors.New("copy data failed")
}
// after
if err = filelock.Copy(unzipRootPath, targetDir); err != nil {
err = fmt.Errorf("copy data dir from [%s] to [%s] failed: %w", unzipRootPath, targetDir, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
const free = await getDiskFree(workspaceDir); // ensure headroom ≥ archive size * 2
if (free < 2 * archiveSize) { throw new Error('insufficient disk space for import'); } Try / catch
try {
await importData(src);
} catch (e) {
if (e.msg === 'copy data failed') {
console.error('Check kernel log "copy data dir from ... failed"; free disk space / clear file locks, then retry');
}
throw e;
} Prevention
- Verify free disk space before large imports (archive needs roughly 2x its size)
- Close other kernel instances and pause sync clients during import
- Fix data-dir ownership/permissions after restoring workspaces from backups
When it happens
Trigger: Importing a data archive whose unzip succeeded but whose copy into util.DataDir failed — e.g. insufficient disk space, a file in the archive colliding with a locked destination file, or OS permission errors inside the workspace data dir.
Common situations: 1) Disk full when importing a large archive. 2) Another SiYuan instance holds locks in the data directory on Windows. 3) Data dir restored from backup with restrictive ownership/permissions. 4) Quota-exceeded cloud-synced workspace folder.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f77e70f2ca8079cb.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/import.go:1140
if strings.HasPrefix(d.Name(), ".") {
return filepath.SkipDir
}
return nil
}
if !strings.HasSuffix(d.Name(), ".sy") {
return nil
}
p := strings.TrimPrefix(path, unzipRootPath)
p = filepath.ToSlash(p)
treePaths = append(treePaths, p)
return nil
})
if err = filelock.Copy(unzipRootPath, targetDir); err != nil {
logging.LogErrorf("copy data dir from [%s] to [%s] failed: %s", unzipRootPath, util.DataDir, err)
err = errors.New("copy data failed")
return
}
boxAbsPath := filepath.Join(util.DataDir, boxID)
importedAvIDs := map[string]struct{}{}
for _, importedAvID := range avIDs {
importedAvIDs[importedAvID] = struct{}{}
}
for _, treePath := range treePaths {
absPath := filepath.Join(targetDir, treePath)
p := strings.TrimPrefix(absPath, boxAbsPath)
p = filepath.ToSlash(p)
cache.RemoveTreeDataInBox(util.GetTreeID(p), boxID)
cache.RemoveDocIALInBox(p, boxID)
tree, err := filesys.LoadTree(boxID, p, luteEngine)
if err != nil {
logging.LogErrorf("load tree [%s] failed: %s", treePath, err)
continueView on GitHub (pinned to 9f775e8a12)