siyuan-note/siyuan · warning

invalid boot appearance selection

Error message

invalid boot appearance selection

What it means

loadBootAppearanceSelection reads the persisted boot appearance selection JSON and rejects it when the schema version does not match the current bootAppearanceSchemaVersion or when provider and appearance are inconsistent (exactly one set). The stored file is discarded and the default selection is returned with this error, so a corrupt/legacy file never produces an invalid splash screen.

Source

Thrown at kernel/model/boot_appearance.go:292

	appearanceDir := filepath.Join(pluginDir, bootAppearanceDirName, appearanceID)
	filePath, contentType, err = validateBootAppearanceResource(pluginDir, appearanceDir, relativePath, "")
	return
}

func loadBootAppearanceSelection() (ret BootAppearanceSelection, err error) {
	ret = defaultBootAppearanceSelection()
	bootAppearanceConfLock.RLock()
	defer bootAppearanceConfLock.RUnlock()
	data, err := filelock.ReadFile(filepath.Join(util.ConfDir, bootAppearanceConfigName))
	if err != nil {
		return ret, err
	}
	if err = gulu.JSON.UnmarshalJSON(data, &ret); err != nil {
		return ret, err
	}
	if ret.SchemaVersion != bootAppearanceSchemaVersion || (ret.Provider == "") != (ret.Appearance == "") {
		return defaultBootAppearanceSelection(), errors.New("invalid boot appearance selection")
	}
	if ret.Provider != "" && (!bazaar.IsValidPackageName(ret.Provider) || !isValidBootAppearanceID(ret.Appearance)) {
		return defaultBootAppearanceSelection(), errors.New("invalid boot appearance selection")
	}
	return
}

func defaultBootAppearanceSelection() BootAppearanceSelection {
	return BootAppearanceSelection{SchemaVersion: bootAppearanceSchemaVersion}
}

func loadSelectedBootAppearance() (selection BootAppearanceSelection, appearance *BootAppearance, err error) {
	selection, err = loadBootAppearanceSelection()
	if err != nil || selection.Provider == "" {
		return
	}
	appearance, err = getBootAppearanceByID(selection.Provider, selection.Appearance)
	if err != nil {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Delete the stored boot appearance selection file so the default selection is recreated on next load.
  2. Re-save the selection via SetBootAppearance with the current kernel version so the file is written with the current schema version.
  3. If hand-editing, set SchemaVersion to the current bootAppearanceSchemaVersion and keep provider/appearance both set or both empty.
  4. Ignore the error if you only need a usable default: callers already fall back to defaultBootAppearanceSelection().

Example fix

// before
// stale file: {"schemaVersion": 1, "provider": "my-theme", "appearance": ""}
// after
model.SetBootAppearance("my-theme", "dark-splash") // rewrites file with current schema version
Defensive patterns

Strategy: fallback

Validate before calling

const selectionOk = (s) => s.schemaVersion === CURRENT && (s.provider === '') === (s.appearance === '')

Type guard

function isValidSelection(s) { return s != null && s.schemaVersion === CURRENT && (s.provider === '') === (s.appearance === '') }

Try / catch

sel, err := model.loadBootAppearanceSelection(data)
if err != nil {
    sel = model.DefaultBootAppearanceSelection() // already the library fallback
}

Prevention

When it happens

Trigger: Starting the kernel or resolving boot appearance assets when the selection file was written by an older version (schemaVersion mismatch); the file was hand-edited or corrupted so provider is set but appearance is empty (or vice versa); the file contains arbitrary JSON whose SchemaVersion field is zero.

Common situations: Upgrading SiYuan across a boot-appearance format change; manual editing or partial writes of the selection file; syncing config files between different versions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/6d38e26b873b8e03. Report an issue: GitHub.