siyuan-note/siyuan · error
invalid attribute view column widths
Error message
invalid attribute view column widths
What it means
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.
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
Example fix
// before
{"avID": avID, "data": JSON.stringify(widths)}
// after
{"avID": avID, "data": widths} // widths = {"colId1": "200px", "colId2": "120px"} Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof data !== "object" || data === null || Array.isArray(data)) throw new Error("widths must be an object of columnId -> string");
Object.values(data).forEach(w => { if (typeof w !== "string") throw new Error("width values must be strings"); }); Type guard
const isWidthMap = (v: unknown): v is Record<string, string> => typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every(w => typeof w === "string");
Try / catch
try { await setAttrViewColWidth(op); } catch (e) { if (String(e).includes("invalid attribute view column widths")) { /* re-send with corrected object payload */ } else throw e; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- must be a string
- [/api/av/batchSetAttributeViewBlockAttrs] parameter [rowID]…
- attribute view item markdown is nil
- block is not a list item
- block [ ] is not an instance of attribute view [ ]
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/e9d21e67b5521114.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:6818
return
}
err = av.SaveAttributeView(attrView)
return
}
func (tx *Transaction) doSetAttrViewColumnsWidth(operation *Operation) (ret *TxErr) {
err := setAttributeViewColsWidth(operation)
if err != nil {
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func setAttributeViewColsWidth(operation *Operation) (err error) {
widthData, ok := operation.Data.(map[string]any)
if !ok {
return fmt.Errorf("invalid attribute view column widths")
}
widths := map[string]string{}
for id, value := range widthData {
width, valueOK := value.(string)
if !valueOK {
return fmt.Errorf("invalid width for attribute view column [%s]", id)
}
widths[id] = width
}
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return err
}
view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
if err != nil {
return err
}View on GitHub (pinned to 9f775e8a12)