siyuan-note/siyuan · error

invalid card cover image

Error message

invalid card cover image

What it means

When setting a card cover position, if a Position object is present its Image field must be a non-empty string of at most 32 KiB. An empty image value or an oversized inline image produces this error. The limit protects the attribute view file from storing huge embedded cover payloads.

Solutions

  1. Provide a non-empty image identifier/value, or omit data.position entirely when only the source changes.
  2. Reduce the inline image payload below 32 KiB (resize/compress, or reference an asset by ID instead of inlining).
  3. Store large images as notebook assets and reference them rather than embedding the content in the operation.

Example fix

// before
{ "position": { "image": "", "x": 10, "y": 20 } }
// after
{ "position": { "image": "20240101120000-abcdefg", "x": 10, "y": 20 } }
Defensive patterns

Strategy: validation

Validate before calling

if (position && (typeof position.image !== "string" || position.image.length === 0 || position.image.length > 32 * 1024)) throw new Error("cover image must be non-empty and <= 32KiB");

Try / catch

try { await setCardCoverPosition(...); } catch (e) { if (String(e).includes("invalid card cover image")) fallbackToSourceOnlyUpdate(); else throw e; }

Prevention

When it happens

Trigger: doSetAttrViewCardCoverPosition called with data.position present but data.position.image being "", or containing an image string (e.g. base64 data URL) longer than 32*1024 characters.

Common situations: Plugins embedding full-resolution screenshots as base64 in the position payload; UI code sending an empty image field while positioning an uploaded cover; copy-paste of oversized data URLs.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/c29a68e098f1eb32. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view.go:2065

	}
	return
}

func setAttrViewCardCoverPosition(operation *Operation) (err error) {
	dataJSON, err := json.Marshal(operation.Data)
	if nil != err {
		return
	}
	var data setAttrViewCardCoverPositionData
	if err = json.Unmarshal(dataJSON, &data); nil != err {
		return
	}
	if !av.IsValidCardCoverSource(data.Source) {
		return fmt.Errorf("invalid card cover source [%s]", data.Source)
	}
	if nil != data.Position {
		if "" == data.Position.Image || 32*1024 < len(data.Position.Image) {
			return errors.New("invalid card cover image")
		}
		if math.IsNaN(data.Position.X) || math.IsInf(data.Position.X, 0) ||
			math.IsNaN(data.Position.Y) || math.IsInf(data.Position.Y, 0) ||
			data.Position.X < 0 || 100 < data.Position.X || data.Position.Y < 0 || 100 < data.Position.Y {
			return fmt.Errorf("invalid card cover position [%v, %v]", data.Position.X, data.Position.Y)
		}
	}

	attrView, err := av.ParseAttributeView(operation.AvID)
	if nil != err {
		return
	}
	if nil == attrView.GetBlockValue(operation.RowID) {
		return fmt.Errorf("attribute view item [%s] not found", operation.RowID)
	}
	view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
	if nil != err {
		return

View on GitHub (pinned to 9f775e8a12)