{"record":{"id":"0323889eaed6d277","repo":"siyuan-note/siyuan","slug":"install-marketplace-package-failed-w-rollback-f","errorCode":null,"errorMessage":"install marketplace package failed: %w; rollback failed: %s","messagePattern":"install marketplace package failed: %w; rollback failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/bazaar/install.go","lineNumber":236,"sourceCode":"\t\treturn statErr\n\t}\n\tif targetExists && !update && containsFile {\n\t\treturn errors.New(\"marketplace package install path already exists\")\n\t}\n\tif update && !targetExists {\n\t\treturn os.ErrNotExist\n\t}\n\n\tif targetExists {\n\t\tif err = os.Rename(installPath, backupPath); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tif err = os.Rename(stagingPath, installPath); err != nil {\n\t\tif targetExists {\n\t\t\tif rollbackErr := os.Rename(backupPath, installPath); rollbackErr != nil {\n\t\t\t\tpreserveOperationPath = true\n\t\t\t\treturn fmt.Errorf(\"install marketplace package failed: %w; rollback failed: %s\", err, rollbackErr)\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\tif targetExists {\n\t\tif removeErr := os.RemoveAll(operationPath); removeErr != nil {\n\t\t\tlogging.LogWarnf(\"remove package backup [%s] failed: %s\", backupPath, removeErr)\n\t\t}\n\t}\n\treturn\n}\n\n// InstallLocalPackage 从已解压并验证的目录安装本地集市包。\nfunc InstallLocalPackage(sourcePath, installPath, pkgType, packageName string, update bool) (err error) {\n\tvar fallbackInstallTime time.Time\n\tif info, statErr := os.Stat(installPath); statErr == nil {\n\t\tfallbackInstallTime = info.ModTime()\n\t}","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/bazaar/install.go#L218-L254","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the preserved .siyuan-package-install-* directory next to installPath: if backup/ still holds the old package, move it back manually to installPath","Check parent-directory permissions and free disk space, remove any leftover .siyuan-package-install-* directories, and retry the install","Uninstall/clean installPath entirely and perform a fresh install (update=false)","Rule out concurrent writers (second kernel instance, AV scanner) before retrying"],"exampleFix":"// before\n// rename failed and backup/ left in .siyuan-package-install-abc1234\n// after (manual recovery)\n// mv data/plugins/.siyuan-package-install-abc1234/backup data/plugins/my-plugin\n// rm -rf data/plugins/.siyuan-package-install-abc1234\n// retry install","handlingStrategy":"try-catch","validationCode":"// preflight: ensure parent dir is writable and on the same device as staging\nif info, err := os.Stat(filepath.Dir(installPath)); err != nil || info.Mode().Perm()&0200 == 0 {\n    return fmt.Errorf(\"install parent dir missing or not writable: %s\", filepath.Dir(installPath))\n}","typeGuard":null,"tryCatchPattern":"if err := bazaar.InstallLocalPackage(src, installPath, pkgType, name, update); err != nil && strings.Contains(err.Error(), \"rollback failed\") {\n    // inspect leftover .siyuan-package-install-* dir; restore backup/ manually, then retry\n}","preventionTips":["Exclude .siyuan-package-install-* temp dirs from antivirus/backup scans","Ensure adequate disk space and writable parent directories before installing","Avoid running a second kernel instance against the same workspace during installs"],"tags":["filesystem","rename","rollback","atomicity"],"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"}