siyuan-note/siyuan · error
marketplace package install path already exists
Error message
marketplace package install path already exists
What it means
Returned by installPackage (kernel/bazaar/install.go:129-136) during a fresh install (update == false) when the target installPath directory already exists and contains one or more entries. This is a deliberate security guard (GHSA-rpx2-p6hp-x5gj) to prevent a newly downloaded package from silently overwriting files in an already-populated directory, which could be exploited to inject malicious content into an existing package.
Source
Thrown at kernel/bazaar/install.go:135
// 文件夹的修改时间设置为当前操作时间
if err = os.Chtimes(installPath, now, now); err != nil {
logging.LogWarnf("set package [%s] folder mtime failed: %s", packageName, err)
}
go incPackageDownloads(repoURL, systemID)
return nil
}
func installPackage(data []byte, installPath, pkgType, packageName string, update bool) (err error) {
// 非更新安装时目标目录已存在且非空则拒绝覆盖,防止把其他包的内容写入已有包目录
// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-rpx2-p6hp-x5gj
if !update {
entries, statErr := os.ReadDir(installPath)
if statErr != nil && !os.IsNotExist(statErr) {
return statErr
}
if 0 < len(entries) {
return errors.New("marketplace package install path already exists")
}
}
tmpPackage := filepath.Join(util.TempDir, "bazaar", "package")
if err = os.MkdirAll(tmpPackage, 0755); err != nil {
return
}
name := gulu.Rand.String(7)
tmp := filepath.Join(tmpPackage, name+".zip")
defer os.RemoveAll(tmp)
if err = os.WriteFile(tmp, data, 0644); err != nil {
return
}
unzipPath := filepath.Join(tmpPackage, name)
defer os.RemoveAll(unzipPath)
if err = gulu.Zip.Unzip(tmp, unzipPath); err != nil {
logging.LogErrorf("write file [%s] failed: %s", installPath, err)View on GitHub (pinned to 251596fc0d)
Solutions
- Uninstall the existing package first via UninstallPackage, then retry the fresh install
- If updating an existing package, call InstallPackage with update=true instead of false
- Manually remove the install directory if it contains only leftover/empty files
- Check for package name collisions — ensure two packages don't share the same install path
Example fix
// before: fresh install over existing directory bazaar.InstallPackage(repoURL, repoHash, installPath, systemID, pkgType, pkgName, false) // after: uninstall first, then install bazaar.UninstallPackage(installPath) bazaar.InstallPackage(repoURL, repoHash, installPath, systemID, pkgType, pkgName, false)
Defensive patterns
Strategy: validation
Validate before calling
func ensureInstallPathAvailable(installPath string, update bool) error {
if update {
return nil
}
entries, err := os.ReadDir(installPath)
if err != nil && !os.IsNotExist(err) {
return err
}
if len(entries) > 0 {
return fmt.Errorf("path %s already exists and is non-empty — uninstall first or use update mode", installPath)
}
return nil
} Prevention
- Check whether the install directory is empty before calling InstallPackage with update=false
- Uninstall existing packages before attempting a fresh install
- Use update=true when upgrading an already-installed package
When it happens
Trigger: Calling InstallPackage with update=false for a package whose install directory (e.g. data/plugins/<name>) already exists and is non-empty.
Common situations: Reinstalling a package that was partially uninstalled (directory left behind); package name collision between two different packages; a previous install left residual files; attempting to install over a manually placed package.
Related errors
- marketplace package name mismatch: expected [%s], got [%s]
- install local marketplace package failed: %w; rollback faile
- invalid marketplace package type
- marketplace package manifest not found or invalid
- remove community package [%s] failed
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/107e366f9fca7ef3.
Report an issue: GitHub.