siyuan-note/siyuan · error

marketplace package install path already exists

Error message

marketplace package install path already exists

What it means

installPackage refuses a fresh (non-update) install when the target install directory already contains any file. This prevents silently clobbering an existing package directory; overwriting is only allowed through the explicit update path.

Solutions

  1. Uninstall the existing package first, then install fresh
  2. Pass update=true (use the marketplace "update" flow) to overwrite in place
  3. Inspect the install path for leftovers from an interrupted operation and remove them manually

Example fix

// before
// InstallPackage(repoURL, pkgName, pkgType, false /* update */)
// after
// UninstallPackage(installPath)
// InstallPackage(repoURL, pkgName, pkgType, false)
Defensive patterns

Strategy: validation

Validate before calling

contains, err := bazaar.PackageDirContainsFile(installPath)
if err == nil && contains {
    return fmt.Errorf("package %s already installed; uninstall or use update", pkgName)
}

Try / catch

if err := InstallPackage(...); err != nil && strings.Contains(err.Error(), "already exists") {
    // either uninstall first or flip update=true and retry
    UninstallPackage(installPath)
    err = InstallPackage(...)
}

Prevention

When it happens

Trigger: Calling InstallPackage (or the kernel install API) for a package whose installPath already has content while update=false.

Common situations: Reinstalling a package that is already installed without using the update flag; a leftover/partial directory from a previously failed uninstall; stale state after manually copying files into the package dir.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/107e366f9fca7ef3. Report an issue: GitHub.

Appendix: source

Thrown at kernel/bazaar/install.go:139

	// 文件夹的修改时间设置为当前操作时间
	if err = os.Chtimes(installPath, now, now); err != nil {
		logging.LogWarnf("set package [%s] folder mtime failed: %s", packageName, err)
	}

	go incPackageDownloads(repoURL, packageName, 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 {
		containsFile, statErr := PackageDirContainsFile(installPath)
		if statErr != nil && !os.IsNotExist(statErr) {
			return statErr
		}
		if containsFile {
			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 9f775e8a12)