{"record":{"id":"5220b43fa843fc2d","repo":"siyuan-note/siyuan","slug":"invalid-card-aspect-ratio-v","errorCode":null,"errorMessage":"invalid card aspect ratio [%v]","messagePattern":"invalid card aspect ratio \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":1343,"sourceCode":"\terr = av.SaveAttributeView(attrView)\n\treturn\n}\n\nfunc (tx *Transaction) doSetAttrViewCardAspectRatioValue(operation *Operation) (ret *TxErr) {\n\tif err := setAttrViewCardAspectRatioValue(operation); nil != err {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc setAttrViewCardAspectRatioValue(operation *Operation) (err error) {\n\tratio, err := getAttrViewOperationNumber(operation)\n\tif nil != err {\n\t\treturn\n\t}\n\tif math.IsNaN(ratio) || math.IsInf(ratio, 0) ||\n\t\tratio < av.CardAspectRatioValueMin || av.CardAspectRatioValueMax < ratio {\n\t\treturn fmt.Errorf(\"invalid card aspect ratio [%v]\", ratio)\n\t}\n\n\tattrView, err := av.ParseAttributeView(operation.AvID)\n\tif err != nil {\n\t\treturn\n\t}\n\tview, err := getAttrViewViewByBlockID(attrView, operation.BlockID)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tswitch view.LayoutType {\n\tcase av.LayoutTypeTable:\n\t\treturn\n\tcase av.LayoutTypeGallery:\n\t\tview.Gallery.CardAspectRatioValue = ratio\n\tcase av.LayoutTypeKanban:\n\t\tview.Kanban.CardAspectRatioValue = ratio","sourceCodeStart":1325,"sourceCodeEnd":1361,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view.go#L1325-L1361","documentation":"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.","triggerScenarios":"Sending a setAttrViewCardAspectRatio transaction operation (via doSetAttrViewCardAspectRatioValue) whose operation data number is NaN, +/-Inf, negative, or larger than av.CardAspectRatioValueMax.","commonSituations":"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.","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."],"exampleFix":"// before\nconst ratio = el.clientWidth / el.clientHeight; // 0 height -> Infinity\npushSetCardAspectRatio(avID, ratio);\n// after\nconst ratio = el.clientHeight > 0 ? el.clientWidth / el.clientHeight : 1;\nif (Number.isFinite(ratio) && ratio >= CardAspectRatioValueMin && ratio <= CardAspectRatioValueMax) {\n  pushSetCardAspectRatio(avID, ratio);\n}","handlingStrategy":"validation","validationCode":"function isValidAspectRatio(r) { return typeof r === 'number' && Number.isFinite(r) && r >= CardAspectRatioValueMin && r <= CardAspectRatioValueMax; }\nif (!isValidAspectRatio(ratio)) throw new RangeError('aspect ratio out of range');","typeGuard":"const isFiniteNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["attribute-view","validation","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}