{"record":{"id":"3151e7ac30d51dee","repo":"siyuan-note/siyuan","slug":"invalid-card-size-preset-v","errorCode":null,"errorMessage":"invalid card size preset [%v]","messagePattern":"invalid card size preset \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":1798,"sourceCode":"\treturn\n}\n\nfunc (tx *Transaction) doSetAttrViewCardSize(operation *Operation) (ret *TxErr) {\n\terr := setAttrViewCardSize(operation)\n\tif err != nil {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc setAttrViewCardSize(operation *Operation) (err error) {\n\tvalue, err := getAttrViewOperationNumber(operation)\n\tif nil != err {\n\t\treturn\n\t}\n\tsize := av.CardSize(value)\n\tif value != math.Trunc(value) || size < av.CardSizeSmall || av.CardSizeLarge < size {\n\t\treturn fmt.Errorf(\"invalid card size preset [%v]\", value)\n\t}\n\n\tattrView, err := av.ParseAttributeView(operation.AvID)\n\tif err != nil {\n\t\treturn\n\t}\n\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.CardSize = size\n\t\tview.Gallery.CardWidth = av.CardWidthBySize(size)","sourceCodeStart":1780,"sourceCodeEnd":1816,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view.go#L1780-L1816","documentation":"setAttrViewCardSize validates that the numeric value is an integer that maps to a defined av.CardSize preset between CardSizeSmall and CardSizeLarge; fractional values or out-of-preset integers are rejected. Card size is an enum-like preset, not a free-form number.","triggerScenarios":"Sending a setAttrViewCardSize transaction operation whose number is fractional (e.g. 1.5) or outside the small..large preset range (negative, > av.CardSizeLarge).","commonSituations":"Plugin treats card size as a pixel value and passes raw sizes; UI slider emits floats; stale code using removed preset indices.","solutions":["Pass only defined av.CardSize presets (Math.floor the value and check it is within CardSizeSmall..CardSizeLarge).","Convert any pixel-based sizing in the caller to the nearest valid preset before sending the operation.","Update plugin constants if the preset enum changed between kernel versions."],"exampleFix":"// before\nsetCardSize(avID, el.offsetWidth); // pixels\n// after\nconst preset = Math.min(CardSizeLarge, Math.max(CardSizeSmall, Math.round(el.offsetWidth / 200)));\nsetCardSize(avID, preset);","handlingStrategy":"validation","validationCode":"const n = Number(value);\nif (!Number.isInteger(n) || n < CardSizeSmall || n > CardSizeLarge) throw new RangeError('invalid card size preset');","typeGuard":"const isCardSize = (v: unknown): v is number => Number.isInteger(v) && v >= CardSizeSmall && v <= CardSizeLarge;","tryCatchPattern":"try { await setCardSize(avID, value); } catch (e) { if (String(e).includes('invalid card size preset')) { await setCardSize(avID, CardSizeSmall); } else throw e; }","preventionTips":["Use the named CardSize enum members, never raw numbers or pixels","Math.round/validate any computed preset before sending","Keep enum constants in sync with the kernel version"],"tags":["attribute-view","enum","validation"],"backgroundTag":"invalid-enum-value","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"}