siyuan-note/siyuan · error

rename path failed

Error message

rename path failed

What it means

This is a legacy 'rename doc' path in import.go that moves previously exported/imported paths within a notebook (oldPaths -> renamePaths mapping, sorted shallowest-first). If filelock.Rename fails for any pair, the function logs the underlying OS error and replaces it with the generic message 'rename path failed'. The real cause (locked file, missing source, cross-device link) is only visible in the kernel log.

Solutions

  1. Check the kernel log for the 'rename path from [...] to [...] failed' line to find the real OS error and the specific paths involved.
  2. Ensure no other SiYuan instance / antivirus locks files in the workspace's data directory, then retry the import.
  3. Verify the source .sy files referenced by oldPaths exist; restore them or re-export the package.
  4. Run the kernel with sufficient permissions over the workspace, and keep data on a local filesystem rather than a network share.

Example fix

// before
if err = filelock.Rename(oldPath, newPath); err != nil {
    err = errors.New("rename path failed")
}
// after
if err = filelock.Rename(oldPath, newPath); err != nil {
    err = fmt.Errorf("rename path from [%s] to [%s] failed: %w", oldPath, newPath, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

for (const p of [oldPath, newPath]) {
  if (!fs.existsSync(p) && fs.existsSync(oldPath)) { throw new Error(`missing rename source ${oldPath}`); }
}

Try / catch

try {
  await importSY(boxID, src);
} catch (e) {
  if (e.msg === 'rename path failed') {
    console.error('Check kernel log for "rename path from ... failed"; close other SiYuan instances and retry');
  }
  throw e;
}

Prevention

When it happens

Trigger: ImportSY processing a package whose payload includes path-rename operations, when filelock.Rename(oldPath, newPath) fails — e.g. the source .sy file is missing, the target path already exists, file locks/permissions block the move on Windows, or the data dir is on a different filesystem.

Common situations: 1) Antivirus/indexer (or another SiYuan instance) holds the file open on Windows, breaking rename. 2) Stale renamePaths referencing documents deleted between export and import. 3) Workspace on a network mount where rename semantics differ. 4) Permission mismatch after copying a workspace with different ownership.

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/553e46767a5b5129. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/import.go:1023

				buf.WriteString("/")
			}
		}
		newPath := buf.String()
		renamePaths[originalPath] = filepath.Join(unzipRootPath, newPath)
	}

	var oldPaths []string
	for oldPath := range renamePaths {
		oldPaths = append(oldPaths, oldPath)
	}
	sort.Slice(oldPaths, func(i, j int) bool {
		return strings.Count(oldPaths[i], string(os.PathSeparator)) < strings.Count(oldPaths[j], string(os.PathSeparator))
	})
	for i, oldPath := range oldPaths {
		newPath := renamePaths[oldPath]
		if err = filelock.Rename(oldPath, newPath); err != nil {
			logging.LogErrorf("rename path from [%s] to [%s] failed: %s", oldPath, renamePaths[oldPath], err)
			err = errors.New("rename path failed")
			return
		}

		delete(renamePaths, oldPath)
		var toRemoves []string
		newRenamedPaths := map[string]string{}
		for oldP, newP := range renamePaths {
			if strings.HasPrefix(oldP, oldPath) {
				renamedOldP := strings.Replace(oldP, oldPath, newPath, 1)
				newRenamedPaths[renamedOldP] = newP
				toRemoves = append(toRemoves, oldPath)
			}
		}
		for _, toRemove := range toRemoves {
			delete(renamePaths, toRemove)
		}
		maps.Copy(renamePaths, newRenamedPaths)
		for j := i + 1; j < len(oldPaths); j++ {

View on GitHub (pinned to 9f775e8a12)