{"record":{"id":"4cfc669b17f51ce9","repo":"siyuan-note/siyuan","slug":"invalid-card-width-v","errorCode":null,"errorMessage":"invalid card width [%v]","messagePattern":"invalid card width \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/attribute_view.go","lineNumber":1694,"sourceCode":"\terr = av.SaveAttributeView(attrView)\n\treturn\n}\n\nfunc (tx *Transaction) doSetAttrViewCardWidth(operation *Operation) (ret *TxErr) {\n\tif err := setAttrViewCardWidth(operation); nil != err {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc setAttrViewCardWidth(operation *Operation) (err error) {\n\tvalue, err := getAttrViewOperationNumber(operation)\n\tif nil != err {\n\t\treturn\n\t}\n\tif math.IsNaN(value) || math.IsInf(value, 0) || value != math.Trunc(value) ||\n\t\tvalue < av.CardWidthMin || av.CardWidthMax < value {\n\t\treturn fmt.Errorf(\"invalid card width [%v]\", value)\n\t}\n\twidth := int(value)\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.CardWidth = width\n\tcase av.LayoutTypeKanban:","sourceCodeStart":1676,"sourceCodeEnd":1712,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view.go#L1676-L1712","documentation":"Returned by setAttrViewCardWidth (attribute_view.go:1694), dispatched through the transaction action \"setAttrViewCardWidth\". The value must be a finite float64, a whole number (value == math.Trunc(value)), and within [av.CardWidthMin=140, av.CardWidthMax=600]. It is then truncated to int and stored as the pixel width.","triggerScenarios":"Frontend sends a card width that is NaN/Inf, fractional, below 140, or above 600. This is the free-form width path for gallery/kanban cards, independent of the size preset.","commonSituations":"UI slider allowed a value outside 140–600; plugin submitted a fractional CSS width; negative or zero sent by a reset control that did not clamp.","solutions":["Clamp the width to [140, 600] and round to an integer before sending.","Reflect the same bounds in the UI control so the user cannot enter an out-of-range value.","If using a size preset instead, use setAttrViewCardSize and let CardWidthBySize compute the width."],"exampleFix":"// before: raw slider value, possibly out of range\ntransaction({ op: \"setAttrViewCardWidth\", data: sliderValue })\n\n// after: clamp and integerize\nconst width = Math.round(Math.min(600, Math.max(140, sliderValue)))\ntransaction({ op: \"setAttrViewCardWidth\", data: width })","handlingStrategy":"validation","validationCode":"// Clamp and round the width to an integer in [140, 600].\nif (!Number.isFinite(value)) throw new Error('width must be finite')\nconst width = Math.round(Math.min(600, Math.max(140, value)))","typeGuard":"function isValidCardWidth(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v) && Number.isInteger(v) && v >= 140 && v <= 600\n}","tryCatchPattern":null,"preventionTips":["Constrain the width slider to 140–600 and step by 1.","Round to an integer before sending — fractional values are rejected.","Prefer the size preset if only small/medium/large is needed."],"tags":["attribute-view","av","gallery","kanban","card","validation","transaction"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}