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
- Open conf.json and set system.updateChannel to a valid value: 'stable' (or the supported preview channel name used by isValidUpdateChannel)
- Restart the kernel so the corrected config is loaded
- If the value was set by a plugin/script, fix the writer to only use constants from kernel/conf
- 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
- Only set updateChannel through the UI or conf constants, never by hand-editing conf.json
- Validate the value after config load and fall back to 'stable' with a warning
- When renaming channels, add a migration that maps old names to new ones
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
- Argon2id Iterations too high (maximum 10)
- Argon2id Memory too high (maximum 256 MB)
- Argon2id Parallelism must be between 1 and 16
- builtin color must not be null
- builtin style must not be null
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)