siyuan-note/siyuan · warning

invalid card layout [%v]

Error message

invalid card layout [%v]

What it means

Returned by setAttrViewCardLayout (attribute_view.go:1734), dispatched through the transaction action "setAttrViewCardLayout". operation.Data must be a float64 (else error 437), a whole number (value == math.Trunc(value)), and av.CardLayout(value).IsValid() — i.e. within [CardLayoutList=0, CardLayoutCompact=1]. The enum has only two members (list layout, compact layout).

Source

Thrown at kernel/model/attribute_view.go:1734

	err = av.SaveAttributeView(attrView)
	return
}

func (tx *Transaction) doSetAttrViewCardLayout(operation *Operation) (ret *TxErr) {
	if err := setAttrViewCardLayout(operation); nil != err {
		return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
	}
	return
}

func setAttrViewCardLayout(operation *Operation) (err error) {
	value, err := getAttrViewOperationNumber(operation)
	if nil != err {
		return
	}
	layout := av.CardLayout(value)
	if value != math.Trunc(value) || !layout.IsValid() {
		return fmt.Errorf("invalid card layout [%v]", value)
	}

	attrView, err := av.ParseAttributeView(operation.AvID)
	if err != nil {
		return
	}
	view, err := getAttrViewOperationView(attrView, operation)
	if err != nil {
		return
	}

	switch view.LayoutType {
	case av.LayoutTypeGallery:
		view.Gallery.CardLayout = layout
	case av.LayoutTypeKanban:
		view.Kanban.CardLayout = layout
	default:
		return av.ErrWrongLayoutType

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Send only 0 (CardLayoutList) or 1 (CardLayoutCompact) as an integer.
  2. Derive the value from the UI toggle rather than computing it.
  3. Re-validate with av.CardLayout(value).IsValid() semantics: the value must equal its truncation and be 0 or 1.

Example fix

// before: arbitrary code
transaction({ op: "setAttrViewCardLayout", data: layoutCode })

// after: only the two valid modes
const layout = compact ? 1 : 0
transaction({ op: "setAttrViewCardLayout", data: layout })
Defensive patterns

Strategy: validation

Validate before calling

// Card layout has only two modes: 0 (list) and 1 (compact).
if (![0,1].includes(data) || !Number.isInteger(data)) {
  throw new Error('card layout must be 0 or 1')
}

Type guard

function isCardLayoutPreset(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && (v === 0 || v === 1)
}

Prevention

When it happens

Trigger: Frontend sends setAttrViewCardLayout with a non-integer (e.g. 0.5) or an integer outside 0–1 (e.g. 2). Only two field-layout modes exist for gallery/kanban cards.

Common situations: Plugin sends an arbitrary layout code; future layout added to the enum but the guard not updated (here the guard delegates to CardLayout.IsValid so it stays in sync); corrupted persisted value.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/ea2b27027062b387. Report an issue: GitHub.