siyuan-note/siyuan · error

update channel is invalid

Error message

update channel is invalid

What it means

getUpdateRelease routes update checks by Conf.System.UpdateChannel. The stable channel is handled specially; every other value must pass isValidUpdateChannel (pre-release channels like 'preview'). If the configured channel is neither 'stable' nor a valid known channel, the check aborts with this error instead of querying GitHub. It guards against typos or corrupted configuration values.

Solutions

  1. Open conf.json and set system.updateChannel to a valid value: 'stable' (or the supported preview channel name used by isValidUpdateChannel)
  2. Restart the kernel so the corrected config is loaded
  3. If the value was set by a plugin/script, fix the writer to only use constants from kernel/conf
  4. Check for config-sync or restore tooling that may have rewritten updateChannel from an older version

Example fix

// before (conf.json)
"updateChannel": "beta"
// after
"updateChannel": "stable"
Defensive patterns

Strategy: validation

Validate before calling

channel := Conf.System.UpdateChannel
if conf.UpdateChannelStable != channel && !isValidUpdateChannel(channel) {
    logging.LogWarnf("invalid update channel %q, falling back to stable", channel)
    Conf.System.UpdateChannel = conf.UpdateChannelStable
}

Type guard

func isValidChannel(v string) bool { return conf.UpdateChannelStable == v || isValidUpdateChannel(v) }

Prevention

When it happens

Trigger: Calling checkDownloadInstallPkg, getUpdatePkg, or CheckUpdate while Conf.System.UpdateChannel holds a value that is not conf.UpdateChannelStable and not accepted by isValidUpdateChannel — e.g. a hand-edited conf.json, a stale/renamed channel string after an upgrade, or programmatic writes of an arbitrary channel name.

Common situations: Users or scripts editing conf.json's system.updateChannel by hand; syncing an old config into a newer kernel where a channel name was renamed; plugins or automation writing invalid channel values; corrupted config after a crash.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/updater_release.go:87

	Digest             string `json:"digest"`
	State              string `json:"state"`
}

var (
	cachedGitHubReleases    []*githubRelease
	githubReleasesCacheTime int64
	githubReleasesLock      sync.RWMutex
	githubReleasesFlight    singleflight.Group
	githubManifestCache     sync.Map
)

func getUpdateRelease(force bool) (*updateRelease, error) {
	channel := Conf.System.UpdateChannel
	if conf.UpdateChannelStable == channel {
		return getStableUpdateRelease(force)
	}
	if !isValidUpdateChannel(channel) {
		return nil, errors.New("update channel is invalid")
	}
	return getGitHubUpdateRelease(channel, force)
}

func getStableUpdateRelease(force bool) (*updateRelease, error) {
	result, err := util.GetRhyResult(context.TODO(), force)
	if err != nil {
		return nil, err
	}
	version, ok := result["ver"].(string)
	normalizedVersion := normalizeReleaseVersion(version)
	if !ok || !semver.IsValid(normalizedVersion) || "" != semver.Prerelease(normalizedVersion) {
		return nil, errors.New("stable release version is invalid")
	}
	version = strings.TrimPrefix(normalizedVersion, "v")

	release := &updateRelease{
		Version:    version,

View on GitHub (pinned to 9f775e8a12)