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.FitView on GitHub (pinned to 8641553a1f)
Solutions
- Set each layer's type to exactly "image" or "video"
- Change unsupported media (GIF/WebM) to an accepted format: convert GIF to .png/.jpg/.webp image or WebM to .mp4 video
- Update the plugin/kernel so both sides agree on supported layer types
- 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
- Use only the literal strings "image" and "video" for layer type
- Convert GIF/WebM assets to accepted formats (webp/png/jpg, mp4) at build time
- Type the layer type as a union in your manifest typings so typos fail compilation
- Avoid trailing whitespace when editing manifests by hand
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
- too many layers: %d
- invalid or duplicate layer ID
- video poster is required
- image layer cannot declare a poster
- 199
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/324fd9cd78b11d4c.
Report an issue: GitHub.