{"record":{"id":"e9d21e67b5521114","repo":"siyuan-note/siyuan","slug":"invalid-attribute-view-column-widths","errorCode":null,"errorMessage":"invalid attribute view column widths","messagePattern":"invalid attribute view column widths","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":6818,"sourceCode":"\t\treturn\n\t}\n\n\terr = av.SaveAttributeView(attrView)\n\treturn\n}\n\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}","sourceCodeStart":6800,"sourceCodeEnd":6836,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view.go#L6800-L6836","documentation":"setAttributeViewColsWidth is called via the transactions API with an operation whose Data payload holds the column widths. The kernel asserts that Data is a map[string]any (column ID -> width string). If the payload arrived in any other shape (string, nil, array), the type assertion fails and this error is returned instead of applying widths.","triggerScenarios":"Calling the setAttrViewColWidth transaction (or api/transaction route) with operation.Data set to a non-map value, e.g. a JSON string of widths instead of an object, or omitting Data entirely so it is nil.","commonSituations":"Client/plugin sends widths as a pre-serialized JSON string; a newer frontend talks to an older kernel with a different payload shape; hand-written API scripts build the operation wrongly.","solutions":["Send operation.Data as a JSON object mapping column (field) IDs to width strings, e.g. {\"20240101xxxx\": \"200px\"}","Ensure Data is not nil/omitted in the transaction operation","Upgrade frontend/plugin code so the payload shape matches the current kernel API"],"exampleFix":"// before\n{\"avID\": avID, \"data\": JSON.stringify(widths)}\n// after\n{\"avID\": avID, \"data\": widths} // widths = {\"colId1\": \"200px\", \"colId2\": \"120px\"}","handlingStrategy":"type-guard","validationCode":"if (typeof data !== \"object\" || data === null || Array.isArray(data)) throw new Error(\"widths must be an object of columnId -> string\");\nObject.values(data).forEach(w => { if (typeof w !== \"string\") throw new Error(\"width values must be strings\"); });","typeGuard":"const isWidthMap = (v: unknown): v is Record<string, string> =>\n  typeof v === \"object\" && v !== null && !Array.isArray(v) &&\n  Object.values(v).every(w => typeof w === \"string\");","tryCatchPattern":"try { await setAttrViewColWidth(op); } catch (e) { if (String(e).includes(\"invalid attribute view column widths\")) { /* re-send with corrected object payload */ } else throw e; }","preventionTips":["Always send Data as an object, never a JSON string","Include units in width strings (\"200px\")","Write a client-side schema check before queueing the transaction"],"tags":["attribute-view","api","type-mismatch"],"backgroundTag":"type-mismatch","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"}