siyuan-note/siyuan · error
invalid appearance mode
Error message
invalid appearance mode: %s
What it means
SetTheme accepts appearanceMode only as one of the literals "light", "dark", or "system" (empty string skips OS-mode handling). Any other string is rejected with this error and the appearance configuration is left unchanged.
Solutions
- Send exactly "light", "dark", or "system" (or omit/empty to leave the OS mode unchanged)
- Fix case-sensitivity: lowercase the value before sending
- Map your app's internal mode enum to the three accepted literals before calling
- Align frontend and kernel versions so both understand the same appearanceMode values
Example fix
// before
SetTheme("daylight", []int{0}, "auto")
// after
SetTheme("daylight", []int{0}, "system") Defensive patterns
Strategy: validation
Validate before calling
const allowed = ["", "light", "dark", "system"];
if (!allowed.includes(appearanceMode)) throw new Error(`appearanceMode must be one of ${allowed.join("|")}`); Type guard
const isAppearanceMode = (v) => typeof v === "string" && ["", "light", "dark", "system"].includes(v);
Try / catch
try {
await setTheme(theme, modes, appearanceMode);
} catch (e) {
if (String(e).includes("invalid appearance mode")) {
// normalize your enum to "light"|"dark"|"system" and retry
}
} Prevention
- Only send the exact lowercase literals "light", "dark", "system" (or empty to skip)
- Map internal mode enums to the accepted literals at the call boundary
- Add a unit test covering each accepted appearanceMode value
- Keep frontend and kernel versions in sync so mode vocabularies match
When it happens
Trigger: Calling the setAppearance API with appearanceMode set to something other than "", "light", "dark", or "system" (e.g. "auto", "Light", "os", or a numeric value as a string).
Common situations: Script or plugin passes an internal enum like "auto" or 2; case mismatch ("Light"); frontend upgrade sends a new value an older kernel does not know; hand-edited request body.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- theme [ ] not exists or not available for dark mode
- theme [ ] not exists or not available for light mode
- unsupported attribute view key type
- unsupported block operation
- Access to encrypted notebook data is not supported via this…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/2bad57dca05c7ede.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/appearance.go:114
return fmt.Errorf("theme [%s] not exists or not available for dark mode", theme)
}
Conf.Appearance.ThemeDark = theme
}
}
}
if appearanceMode != "" {
switch appearanceMode {
case "light":
Conf.Appearance.ModeOS = false
Conf.Appearance.Mode = 0
case "dark":
Conf.Appearance.ModeOS = false
Conf.Appearance.Mode = 1
case "system":
Conf.Appearance.ModeOS = true
default:
return fmt.Errorf("invalid appearance mode: %s", appearanceMode)
}
}
return nil
}
func containTheme(name string, themes []*conf.AppearanceTheme) bool {
for _, t := range themes {
if t.Name == name {
return true
}
}
return false
}
func containIcon(name string, icons []*conf.AppearanceIcon) bool {
for _, i := range icons {
if i.Name == name {
return trueView on GitHub (pinned to 9f775e8a12)