siyuan-note/siyuan · error

image layer cannot declare a poster

Error message

image layer cannot declare a poster

What it means

Poster is only meaningful for video layers. If an "image" layer sets a non-empty poster field, loadBootAppearance rejects the manifest, because images render directly and have no pre-load placeholder.

Source

Thrown at kernel/model/boot_appearance.go:476

		}
		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.Position
		if position == "" {
			position = "center"
		}
		if !isValidBootAppearancePosition(position) {
			err = fmt.Errorf("invalid layer position [%s]", position)
			return nil, err
		}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Remove the poster field (or set it to "") from every image-type layer in manifest.json
  2. Keep the poster field only on layers whose type is "video"
  3. If you intended a video, change the layer type back to "video" and keep src as an .mp4 with the poster retained

Example fix

// before
{"id": "bg", "type": "image", "src": "bg.png", "poster": "bg-thumb.png"}
// after
{"id": "bg", "type": "image", "src": "bg.png"}
Defensive patterns

Strategy: validation

Validate before calling

manifest.layers?.forEach(l => {
  if (l.type !== "video" && l.poster) throw new Error(`image layer ${l.id} must not declare poster`);
});

Type guard

type Layer = { type: "image"; src: string; poster?: never } | { type: "video"; src: string; poster: string };

Prevention

When it happens

Trigger: GetBootAppearances/getBootAppearanceByID loading a manifest.json where a layer with "type": "image" (or a non-video type) declares a poster value. Typically happens after switching a layer's src from video to image while keeping the poster field, or copy-pasting a video layer object.

Common situations: Author replaces an animated video layer with a static image but leaves "poster" in the JSON; a manifest template that always includes poster for every layer; bulk-generated manifests that emit poster unconditionally.

Related errors


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