siyuan-note/siyuan · error

unsupported layer type [%s]

Error message

unsupported layer type [%s]

What it means

loadBootAppearance rejects a boot-appearance manifest whose style layer type is not one of the supported layer kinds. Unknown layer type strings in the manifest's Layers array fail this format check while loading an appearance package.

Source

Thrown at kernel/model/boot_appearance.go:461

	ret.OfficialUI.ProgressColor = manifest.OfficialUI.ProgressColor
	ret.OfficialUI.TrackColor = manifest.OfficialUI.TrackColor

	if manifest.Style != "" {
		if _, _, err = validateBootAppearanceResource(pluginDir, appearanceDir, manifest.Style, "style"); err != nil {
			return nil, fmt.Errorf("invalid style: %w", err)
		}
		ret.Style = bootAppearanceAssetURL(pkg.Name, appearanceID, manifest.Style)
	}

	layerIDs := map[string]bool{}
	for _, layer := range manifest.Layers {
		if layer == nil || !isValidBootAppearanceID(layer.ID) || layerIDs[layer.ID] {
			err = errors.New("invalid or duplicate layer ID")
			return nil, err
		}
		layerIDs[layer.ID] = true
		if layer.Type != "image" && layer.Type != "video" {
			err = fmt.Errorf("unsupported layer type [%s]", layer.Type)
			return nil, err
		}
		if _, _, err = validateBootAppearanceResource(pluginDir, appearanceDir, layer.Src, layer.Type); err != nil {
			return nil, fmt.Errorf("invalid layer source: %w", err)
		}
		if layer.Type == "video" {
			if layer.Poster == "" {
				err = errors.New("video poster is required")
				return nil, err
			}
			if _, _, err = validateBootAppearanceResource(pluginDir, appearanceDir, layer.Poster, "image"); err != nil {
				return nil, fmt.Errorf("invalid video poster: %w", err)
			}
		} else if layer.Poster != "" {
			err = errors.New("image layer cannot declare a poster")
			return nil, err
		}
		fit := layer.Fit

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Set each layer's type to exactly "image" or "video"
  2. Change unsupported media (GIF/WebM) to an accepted format: convert GIF to .png/.jpg/.webp image or WebM to .mp4 video
  3. Update the plugin/kernel so both sides agree on supported layer types
  4. Remove layers with invalid types if they are not needed

Example fix

// before
{"id": "logo", "type": "gif", "src": "logo.gif"}
// after
{"id": "logo", "type": "image", "src": "logo.webp"}
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_TYPES = new Set(["image", "video"]);
manifest.layers?.forEach(l => {
  if (!ALLOWED_TYPES.has(l.type)) throw new Error(`layer ${l.id}: type must be "image" or "video"`);
});

Type guard

const isLayerType = (t: unknown): t is "image" | "video" => t === "image" || t === "video";

Prevention

When it happens

Trigger: GetBootAppearances/getBootAppearanceByID loading a manifest.json where some layer's type is missing, misspelled (e.g. "Image", "img", "gif"), or a new experimental type not supported by the running kernel version.

Common situations: Manifest authored against a hypothetical/patched kernel that allows other layer types; typo 'type': 'image ' with trailing space; author assumed GIF/WebM layers work; type field omitted when constructing the layer object.

Related errors


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