siyuan-note/siyuan · error
invalid card aspect ratio
Error message
invalid card aspect ratio [%v]
What it means
This error is thrown when an attribute-view transaction operation tries to set a gallery/kanban card aspect ratio to a value that is NaN, infinite, or outside the allowed range [av.CardAspectRatioValueMin, av.CardAspectRatioValueMax]. The kernel validates the ratio number from getAttrViewOperationNumber before parsing or mutating the attribute view, so invalid values never touch stored data.
Solutions
- Clamp/validate the ratio client-side against av.CardAspectRatioValueMin and av.CardAspectRatioValueMax before enqueueing the transaction operation.
- Ensure the ratio is computed from real rendered dimensions; guard against division by zero or undefined width/height.
- Update plugin code to the current CardAspectRatioValue bounds if it was written against an older kernel version.
- Retry the operation with a valid finite number within range.
Example fix
// before
const ratio = el.clientWidth / el.clientHeight; // 0 height -> Infinity
pushSetCardAspectRatio(avID, ratio);
// after
const ratio = el.clientHeight > 0 ? el.clientWidth / el.clientHeight : 1;
if (Number.isFinite(ratio) && ratio >= CardAspectRatioValueMin && ratio <= CardAspectRatioValueMax) {
pushSetCardAspectRatio(avID, ratio);
} Defensive patterns
Strategy: validation
Validate before calling
function isValidAspectRatio(r) { return typeof r === 'number' && Number.isFinite(r) && r >= CardAspectRatioValueMin && r <= CardAspectRatioValueMax; }
if (!isValidAspectRatio(ratio)) throw new RangeError('aspect ratio out of range'); Type guard
const isFiniteNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);
Try / catch
try { await setCardAspectRatio(avID, ratio); } catch (e) { if (String(e).includes('invalid card aspect ratio')) { console.warn('ratio rejected, clamping'); await setCardAspectRatio(avID, clamp(ratio)); } else throw e; } Prevention
- Always guard divisions used to compute the ratio against zero-height
- Clamp against the exported CardAspectRatioValueMin/Max constants before sending
- Re-check constants after kernel upgrades
When it happens
Trigger: Sending a setAttrViewCardAspectRatio transaction operation (via doSetAttrViewCardAspectRatioValue) whose operation data number is NaN, +/-Inf, negative, or larger than av.CardAspectRatioValueMax.
Common situations: Frontend or plugin computes the ratio from element dimensions that are 0 or not yet laid out (division by zero producing NaN/Inf); stale plugin code using an old ratio range after the kernel added min/max bounds; manual transaction crafting with a typo'd value.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- builtin color index [ ] must be between and
- invalid card width [ ]
- at least one visible view is required
- attribute view custom color index
- attribute view custom color must not be null
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/5220b43fa843fc2d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:1343
err = av.SaveAttributeView(attrView)
return
}
func (tx *Transaction) doSetAttrViewCardAspectRatioValue(operation *Operation) (ret *TxErr) {
if err := setAttrViewCardAspectRatioValue(operation); nil != err {
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func setAttrViewCardAspectRatioValue(operation *Operation) (err error) {
ratio, err := getAttrViewOperationNumber(operation)
if nil != err {
return
}
if math.IsNaN(ratio) || math.IsInf(ratio, 0) ||
ratio < av.CardAspectRatioValueMin || av.CardAspectRatioValueMax < ratio {
return fmt.Errorf("invalid card aspect ratio [%v]", ratio)
}
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.CardAspectRatioValue = ratio
case av.LayoutTypeKanban:
view.Kanban.CardAspectRatioValue = ratioView on GitHub (pinned to 9f775e8a12)