siyuan-note/siyuan · error
video poster is required
Error message
video poster is required
What it means
Video layers must declare a poster image: if layer.Type is "video" and layer.Poster is empty, loadBootAppearance aborts. The poster is shown before the video loads/plays on the boot screen, so it is mandatory for video layers.
Source
Thrown at kernel/model/boot_appearance.go:469
}
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
if fit == "" {
fit = "cover"
}
if !isValidBootAppearanceFit(fit) {
err = fmt.Errorf("invalid layer fit [%s]", fit)
return nil, err
}
position := layer.PositionView on GitHub (pinned to 8641553a1f)
Solutions
- Add a poster field pointing to a PNG/JPEG/WebP image in the appearance directory for every video layer
- Generate a poster by exporting a frame of the video (e.g. first frame) as poster.png
- Re-validate the manifest so the video layer reads like {"type":"video","src":"x.mp4","poster":"poster.png"}
Example fix
// before
{"id": "anim", "type": "video", "src": "anim.mp4"}
// after
{"id": "anim", "type": "video", "src": "anim.mp4", "poster": "anim-poster.png"} Defensive patterns
Strategy: validation
Validate before calling
manifest.layers?.forEach(l => {
if (l.type === "video" && (!l.poster || typeof l.poster !== "string")) {
throw new Error(`video layer ${l.id} requires a poster`);
}
}); Type guard
const hasPoster = (l: { type: string; poster?: string }): boolean =>
l.type !== "video" || (typeof l.poster === "string" && l.poster.length > 0); Prevention
- Always export a poster frame when adding a video layer
- Template your video-layer JSON with poster included
- Lint manifests so video layers without poster fail the build
- Keep the poster next to the video in the same directory
When it happens
Trigger: GetBootAppearances/getBootAppearanceByID loading a manifest.json where a layer with "type": "video" omits the poster field or sets it to "".
Common situations: Author adds a video layer copied from an image-layer template that had no poster field; poster considered optional; a generator that only emits src for video layers.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- too many layers: %d
- invalid or duplicate layer ID
- unsupported layer type [%s]
- invalid video poster: %w
- image layer cannot declare a poster
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/16b3fdbeb18019e9.
Report an issue: GitHub.