siyuan-note/siyuan · warning

invalid card aspect ratio preset [%v]

Error message

invalid card aspect ratio preset [%v]

What it means

Returned by setAttrViewCardAspectRatio (attribute_view.go:1155), dispatched through the transaction action "setAttrViewCardAspectRatio". The operation.Data must be a float64 (else error 437 from getAttrViewOperationNumber), the value must be a whole number (value == math.Trunc(value)), and av.CardAspectRatio(value) must fall within [CardAspectRatio16_9=0 .. CardAspectRatio1_1=6]. The error means the preset index is fractional or outside the 0–6 enum range.

Source

Thrown at kernel/model/attribute_view.go:1155

	}
}

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

func setAttrViewCardAspectRatio(operation *Operation) (err error) {
	value, err := getAttrViewOperationNumber(operation)
	if nil != err {
		return
	}
	ratio := av.CardAspectRatio(value)
	if value != math.Trunc(value) || ratio < av.CardAspectRatio16_9 || av.CardAspectRatio1_1 < ratio {
		return fmt.Errorf("invalid card aspect ratio preset [%v]", value)
	}

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

	view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
	if err != nil {
		return
	}

	switch view.LayoutType {
	case av.LayoutTypeTable:
		return
	case av.LayoutTypeGallery:
		view.Gallery.CardAspectRatio = ratio
		view.Gallery.CardAspectRatioValue = av.CardAspectRatioValueByPreset(ratio)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Send one of the documented preset indices 0–6 (matching CardAspectRatio16_9 .. CardAspectRatio1_1), as an integer JSON number.
  2. If you need an arbitrary ratio, use the separate action setAttrViewCardAspectRatioValue (error 427) which accepts a free-form width/height float in [0.25, 2.5].
  3. Re-derive the index from the UI preset selector instead of computing it from the ratio.

Example fix

// before: sending the computed ratio as the preset
transaction({ op: "setAttrViewCardAspectRatio", data: 16/9 })

// after: send the preset enum index (0 = 16:9)
transaction({ op: "setAttrViewCardAspectRatio", data: 0 })
Defensive patterns

Strategy: validation

Validate before calling

// Only send integer preset indices 0..6 for setAttrViewCardAspectRatio.
const VALID = [0,1,2,3,4,5,6]
if (!Number.isInteger(data) || !VALID.includes(data)) {
  throw new Error(`aspect ratio preset must be one of ${VALID}`)
}

Type guard

function isCardAspectRatioPreset(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 6
}

Prevention

When it happens

Trigger: Frontend sends a setAttrViewCardAspectRatio transaction with data that is a non-integer (e.g. 2.5) or an integer outside 0–6 (e.g. -1 or 7). The value selects one of the seven aspect-ratio presets (16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 1:1) for a gallery or kanban view.

Common situations: Plugin constructs the operation manually and passes the raw aspect-ratio number (e.g. 1.78) instead of the preset enum index; stale frontend build whose preset list drifted from the kernel enum; corrupted/persisted config replayed with a bad value.

Related errors


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