siyuan-note/siyuan · error

theme [%s] not exists or not available for light mode

Error message

theme [%s] not exists or not available for light mode

What it means

Returned by SetTheme when modes contains 0 (light) but the requested theme name is not in Conf.Appearance.LightThemes. Light themes are loaded by LoadThemes into the LightThemes slice; SetTheme checks membership by Name before assigning Conf.Appearance.ThemeLight.

Source

Thrown at kernel/model/appearance.go:91

	defer Conf.m.Unlock()

	if !containIcon(icon, Conf.Appearance.Icons) {
		return fmt.Errorf("icon [%s] not exists or not available", icon)
	}
	Conf.Appearance.Icon = icon
	return nil
}

func SetTheme(theme string, modes []int, appearanceMode string) error {
	Conf.m.Lock()
	defer Conf.m.Unlock()

	if theme != "" {
		for _, mode := range modes {
			switch mode {
			case 0:
				if !containTheme(theme, Conf.Appearance.LightThemes) {
					return fmt.Errorf("theme [%s] not exists or not available for light mode", theme)
				}
				Conf.Appearance.ThemeLight = theme
			case 1:
				if !containTheme(theme, Conf.Appearance.DarkThemes) {
					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

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Install the theme pack, or choose a name from Conf.Appearance.LightThemes (default "daylight").
  2. If the theme is dark-only, do not include mode 0 in the modes slice for that call.
  3. Call SetTheme only after InitAppearance has loaded themes.

Example fix

// before
model.SetTheme("dark-only-theme", []int{0, 1}, "")
// after
model.SetTheme("daylight", []int{0}, "")
Defensive patterns

Strategy: validation

Validate before calling

if !containTheme(name, Conf.Appearance.LightThemes) {
    return fmt.Errorf("theme %q not installed for light mode", name)
}

Type guard

func themeAvailableForMode(name string, themes []*conf.AppearanceTheme) bool {
    for _, t := range themes { if t.Name == name { return true } }
    return false
}

Prevention

When it happens

Trigger: Calling SetTheme with mode 0 and a theme not present among installed light themes — uninstalled theme, typo, or a dark-only theme passed for light mode.

Common situations: A theme pack was uninstalled but the UI/API still sends its name; a theme is dark-only and the caller passes it for both modes; calling before LoadThemes has run.

Related errors


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