siyuan-note/siyuan · error

copy data failed

Error message

copy data failed

What it means

Thrown by ImportSYZip when filelock.Copy fails copying the unzipped content from the temporary extraction directory (unzipRootPath) to the target notebook directory (targetDir under data/boxID/baseTargetPath). This copy happens after block-ID regeneration and path renaming, moving the processed .sy files and assets into their final location. The underlying copy error is logged with source and destination paths.

Source

Thrown at kernel/model/import.go:866

			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)
			continue

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Free disk space on the volume containing the SiYuan data directory.
  2. Check file permissions on data/boxID and its parent directories.
  3. Close other applications that may have files open in the data directory.
  4. Inspect the kernel log for the detailed copy error (logged at import.go:865 with unzipRootPath and util.DataDir).
  5. If using a network or cloud-synced data directory, verify connectivity and pause sync tools during import.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before ImportSYZip, verify target directory has enough free space
func checkFreeSpace(targetDir string, zipPath string) error {
    var stat unix.Statfs_t
    if err := unix.Statfs(targetDir, &stat); err != nil {
        return err
    }
    freeBytes := stat.Bavail * uint64(stat.Bsize)
    zipInfo, _ := os.Stat(zipPath)
    needed := uint64(zipInfo.Size()) * 3 // uncompressed estimate
    if freeBytes < needed {
        return fmt.Errorf("insufficient disk space: have %d bytes, need ~%d", freeBytes, needed)
    }
    return nil
}

Try / catch

createdBoxID, err := model.ImportSYZip(boxID, localPath, toPath)
if err != nil && err.Error() == "copy data failed" {
    // Surface a user-friendly message with disk space hint
    logging.LogErrorf("copy failed during .sy.zip import: check disk space and permissions")
}

Prevention

When it happens

Trigger: Calling ImportSYZip where filelock.Copy(unzipRootPath, targetDir) returns a non-nil error at import.go:864-867. The target directory was created with os.MkdirAll just before, so the failure is typically I/O-related rather than a missing parent.

Common situations: Disk full during the copy operation. Permission denied on the target notebook directory. A file in the source is locked by another process. Symlink or special file in the unzipped content that the copy routine cannot handle. Network-mounted data directory with intermittent connectivity.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/f77e70f2ca8079cb. Report an issue: GitHub.