{"record":{"id":"259560d9496f1f75","repo":"siyuan-note/siyuan","slug":"update-channel-is-invalid-259560","errorCode":null,"errorMessage":"update channel is invalid","messagePattern":"update channel is invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/updater_release.go","lineNumber":87,"sourceCode":"\tDigest             string `json:\"digest\"`\n\tState              string `json:\"state\"`\n}\n\nvar (\n\tcachedGitHubReleases    []*githubRelease\n\tgithubReleasesCacheTime int64\n\tgithubReleasesLock      sync.RWMutex\n\tgithubReleasesFlight    singleflight.Group\n\tgithubManifestCache     sync.Map\n)\n\nfunc getUpdateRelease(force bool) (*updateRelease, error) {\n\tchannel := Conf.System.UpdateChannel\n\tif conf.UpdateChannelStable == channel {\n\t\treturn getStableUpdateRelease(force)\n\t}\n\tif !isValidUpdateChannel(channel) {\n\t\treturn nil, errors.New(\"update channel is invalid\")\n\t}\n\treturn getGitHubUpdateRelease(channel, force)\n}\n\nfunc getStableUpdateRelease(force bool) (*updateRelease, error) {\n\tresult, err := util.GetRhyResult(context.TODO(), force)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tversion, ok := result[\"ver\"].(string)\n\tnormalizedVersion := normalizeReleaseVersion(version)\n\tif !ok || !semver.IsValid(normalizedVersion) || \"\" != semver.Prerelease(normalizedVersion) {\n\t\treturn nil, errors.New(\"stable release version is invalid\")\n\t}\n\tversion = strings.TrimPrefix(normalizedVersion, \"v\")\n\n\trelease := &updateRelease{\n\t\tVersion:    version,","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/updater_release.go#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (conf.json)\n\"updateChannel\": \"beta\"\n// after\n\"updateChannel\": \"stable\"","handlingStrategy":"validation","validationCode":"channel := Conf.System.UpdateChannel\nif conf.UpdateChannelStable != channel && !isValidUpdateChannel(channel) {\n    logging.LogWarnf(\"invalid update channel %q, falling back to stable\", channel)\n    Conf.System.UpdateChannel = conf.UpdateChannelStable\n}","typeGuard":"func isValidChannel(v string) bool { return conf.UpdateChannelStable == v || isValidUpdateChannel(v) }","tryCatchPattern":null,"preventionTips":["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"],"tags":["config","update-channel","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}