{"record":{"id":"1783409bfd43d2f6","repo":"siyuan-note/siyuan","slug":"invalid-width-for-attribute-view-column-s","errorCode":null,"errorMessage":"invalid width for attribute view column [%s]","messagePattern":"invalid width for attribute view column \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":6343,"sourceCode":"\nfunc (tx *Transaction) doSetAttrViewColumnsWidth(operation *Operation) (ret *TxErr) {\n\terr := setAttributeViewColsWidth(operation)\n\tif err != nil {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc setAttributeViewColsWidth(operation *Operation) (err error) {\n\twidthData, ok := operation.Data.(map[string]any)\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid attribute view column widths\")\n\t}\n\twidths := map[string]string{}\n\tfor id, value := range widthData {\n\t\twidth, valueOK := value.(string)\n\t\tif !valueOK {\n\t\t\treturn fmt.Errorf(\"invalid width for attribute view column [%s]\", id)\n\t\t}\n\t\twidths[id] = width\n\t}\n\n\tattrView, err := av.ParseAttributeView(operation.AvID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tview, err := getAttrViewViewByBlockID(attrView, operation.BlockID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif av.LayoutTypeTable != view.LayoutType {\n\t\treturn nil\n\t}\n\tfor _, column := range view.Table.Columns {\n\t\tif width, found := widths[column.ID]; found {\n\t\t\tcolumn.Width = av.FilterWidthValue(width)","sourceCodeStart":6325,"sourceCodeEnd":6361,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view.go#L6325-L6361","documentation":"Thrown by setAttributeViewColsWidth when an individual value in the widths map cannot be asserted to string. Even though the overall Data is a map, each width entry must be a string value; numbers, booleans, or objects are rejected.","triggerScenarios":"The widths object contains a numeric value (e.g. 200 instead of \"200\"), null, or a nested object for one of the columns. Often a frontend serialization oversight where a number was not coerced to string.","commonSituations":"Client storing widths as numbers in state and forwarding them unconverted; a column whose width was never set and serializes as null.","solutions":["Coerce every width to a string on the client before constructing the operation (String(width) / width.toString()).","Omit entries whose width is null/undefined instead of sending them.","Add a unit test that the widths payload is always Record<string, string>."],"exampleFix":"// before\nop.Data = { col1: 200, col2: '120px' } // mixed numeric/string\n// after\nop.Data = Object.fromEntries(\n  Object.entries(widths).filter(([, w]) => w != null).map(([id, w]) => [id, String(w)])\n)","handlingStrategy":"type-guard","validationCode":"for (const [id, w] of Object.entries(op.data)) {\n  if (typeof w !== 'string') op.data[id] = String(w) // coerce before sending\n}","typeGuard":"function widthsAreStrings(d: unknown): d is Record<string, string> {\n  return typeof d === 'object' && d !== null && !Array.isArray(d) && Object.values(d).every(v => typeof v === 'string')\n}","tryCatchPattern":null,"preventionTips":["Coerce width values to string at the source (state setter).","Omit null/undefined width entries rather than forwarding them."],"tags":["attribute-view","payload-validation","column-width","transaction"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}