siyuan-note/siyuan · critical

install marketplace package failed: %w; rollback failed: %s

Error message

install marketplace package failed: %w; rollback failed: %s

What it means

During replacePackageDirectory's atomic swap, the final os.Rename of the staged package onto installPath failed, and the attempt to restore the backed-up old package also failed. The error wraps both the primary rename error and the rollback error; the temp operation directory (.siyuan-package-install-*) is preserved for diagnosis. This indicates the install directory is likely left without the package and needs manual repair.

Source

Thrown at kernel/bazaar/install.go:236

		return statErr
	}
	if targetExists && !update && containsFile {
		return errors.New("marketplace package install path already exists")
	}
	if update && !targetExists {
		return os.ErrNotExist
	}

	if targetExists {
		if err = os.Rename(installPath, backupPath); err != nil {
			return
		}
	}
	if err = os.Rename(stagingPath, installPath); err != nil {
		if targetExists {
			if rollbackErr := os.Rename(backupPath, installPath); rollbackErr != nil {
				preserveOperationPath = true
				return fmt.Errorf("install marketplace package failed: %w; rollback failed: %s", err, rollbackErr)
			}
		}
		return
	}
	if targetExists {
		if removeErr := os.RemoveAll(operationPath); removeErr != nil {
			logging.LogWarnf("remove package backup [%s] failed: %s", backupPath, removeErr)
		}
	}
	return
}

// InstallLocalPackage 从已解压并验证的目录安装本地集市包。
func InstallLocalPackage(sourcePath, installPath, pkgType, packageName string, update bool) (err error) {
	var fallbackInstallTime time.Time
	if info, statErr := os.Stat(installPath); statErr == nil {
		fallbackInstallTime = info.ModTime()
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Inspect the preserved .siyuan-package-install-* directory next to installPath: if backup/ still holds the old package, move it back manually to installPath
  2. Check parent-directory permissions and free disk space, remove any leftover .siyuan-package-install-* directories, and retry the install
  3. Uninstall/clean installPath entirely and perform a fresh install (update=false)
  4. Rule out concurrent writers (second kernel instance, AV scanner) before retrying

Example fix

// before
// rename failed and backup/ left in .siyuan-package-install-abc1234
// after (manual recovery)
// mv data/plugins/.siyuan-package-install-abc1234/backup data/plugins/my-plugin
// rm -rf data/plugins/.siyuan-package-install-abc1234
// retry install
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: ensure parent dir is writable and on the same device as staging
if info, err := os.Stat(filepath.Dir(installPath)); err != nil || info.Mode().Perm()&0200 == 0 {
    return fmt.Errorf("install parent dir missing or not writable: %s", filepath.Dir(installPath))
}

Try / catch

if err := bazaar.InstallLocalPackage(src, installPath, pkgType, name, update); err != nil && strings.Contains(err.Error(), "rollback failed") {
    // inspect leftover .siyuan-package-install-* dir; restore backup/ manually, then retry
}

Prevention

When it happens

Trigger: os.Rename(stagingPath, installPath) fails (e.g. installPath re-created by another process, permission change, or cross-device issue) while targetExists is true, and os.Rename(backupPath, installPath) also fails — typically because the backup directory or operation temp directory was deleted or locked mid-operation, or the parent directory became non-writable.

Common situations: Antivirus/backup software locking or deleting the .siyuan-package-install-* temp directory during install; disk full or permission change on the package parent directory (data/plugins, data/themes, etc.); two kernels or a stale process touching the same install path concurrently.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/0323889eaed6d277. Report an issue: GitHub.