siyuan-note/siyuan · error · errUpdatePackageUnavailable

update package is unavailable

Error message

update package is unavailable

What it means

This is the sentinel error declaration `var errUpdatePackageUnavailable = errors.New("update package is unavailable")` at updater.go:59. It is the base of an error family: getUpdatePkg() wraps it with fmt.Errorf("%w ...", errUpdatePackageUnavailable) to add platform/package context. Callers detect any member of this family with errors.Is(err, errUpdatePackageUnavailable), which checkDownloadInstallPkg uses to decide whether to push a 'new version available but no package' notification.

Source

Thrown at kernel/model/updater.go:59

		return ""
	}

	downloadPkgURLs, checksum, err := getUpdatePkg()
	if err != nil {
		return ""
	}

	pkg := path.Base(downloadPkgURLs[0])
	pkgPath := filepath.Join(util.TempDir, "install", pkg)
	localChecksum, _ := sha256Hash(pkgPath)
	if checksum != localChecksum {
		return ""
	}
	return pkgPath
}

var checkDownloadInstallPkgLock = sync.Mutex{}
var errUpdatePackageUnavailable = errors.New("update package is unavailable")

func checkDownloadInstallPkg(notifyPackageUnavailable bool) {
	defer logging.Recover()

	if skipNewVerInstallPkg() {
		return
	}

	if !checkDownloadInstallPkgLock.TryLock() {
		return
	}
	defer checkDownloadInstallPkgLock.Unlock()

	downloadPkgURLs, checksum, err := getUpdatePkg()
	if err != nil {
		if notifyPackageUnavailable && errors.Is(err, errUpdatePackageUnavailable) {
			if release, releaseErr := getUpdateRelease(false); nil == releaseErr && !isVersionUpToDate(release.Version) {
				pushNewVersionNotification(release)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Detect the family with errors.Is(err, model.errUpdatePackageUnavailable) rather than string matching, since the wrapped message varies by platform and package.
  2. If on Linux, install updates via your package manager instead of the in-app updater — the updater only ships Windows (.exe) and macOS (.dmg) artifacts.
  3. If on Windows/macOS, wait for the release to finish uploading all assets, then retry; the release is published before all binaries are attached.

Example fix

// before
if err.Error() == "update package is unavailable" { ... } // fragile, never matches wrapped forms

// after
if errors.Is(err, errUpdatePackageUnavailable) {
    pushNewVersionNotification(release)
}
Defensive patterns

Strategy: try-catch

Try / catch

// In checkDownloadInstallPkg-style callers, distinguish 'no package' from real failures.
_, _, err := getUpdatePkg()
if err != nil {
    if errors.Is(err, errUpdatePackageUnavailable) && notifyPackageUnavailable {
        if release, rerr := getUpdateRelease(false); rerr == nil && !isVersionUpToDate(release.Version) {
            pushNewVersionNotification(release) // tell user a new version exists, just no auto-pkg
        }
    }
    return // not a hard failure
}

Prevention

When it happens

Trigger: The sentinel itself is never returned bare by getUpdatePkg; it is wrapped at lines 119, 124, and 128. It surfaces to callers via errors.Is. It is matched in checkDownloadInstallPkg (line 75) to trigger pushNewVersionNotification when a newer release exists but the current platform has no installable artifact.

Common situations: Running SiYuan on Linux (no .exe/.dmg package produced), on an unsupported architecture (e.g. 386), or when a freshly published release has not yet uploaded all platform assets. The user sees a 'new version available' banner but the auto-download never starts.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/ee11e69acb273e66. Report an issue: GitHub.