siyuan-note/siyuan · error
invalid attribute view column widths
Error message
invalid attribute view column widths
What it means
Thrown by setAttributeViewColsWidth when operation.Data cannot be asserted to map[string]any. The column-width operation expects a JSON object mapping column ID -> width string; any other shape (array, number, string, nil) fails the type assertion immediately.
Source
Thrown at kernel/model/attribute_view.go:6337
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 251596fc0d)
Solutions
- Ensure the operation Data is a JSON object { [columnID: string]: string } before sending the transaction.
- On the client, build the payload with Object.fromEntries rather than pushing into an array.
- If integrating via the HTTP API, validate the JSON shape against the Operation.Data contract before posting.
Example fix
// before
op.Data = [['col1', '200px'], ['col2', '120px']] // array of pairs
// after
op.Data = { col1: '200px', col2: '120px' } // plain object Defensive patterns
Strategy: type-guard
Validate before calling
function isWidthMap(d) {
return d != null && typeof d === 'object' && !Array.isArray(d) && Object.values(d).every(v => typeof v === 'string')
}
if (!isWidthMap(op.data)) { /* rebuild as object { [id]: string } */ } Type guard
type WidthMap = Record<string, string>
function isWidthMap(v: unknown): v is WidthMap {
if (typeof v !== 'object' || v === null || Array.isArray(v)) return false
return Object.values(v).every(x => typeof x === 'string')
} Prevention
- Always build the widths payload as a plain object, not an array of pairs.
- Pin the operation schema in a shared client type and unit-test it.
When it happens
Trigger: A frontend or API caller sends the widths payload as the wrong JSON type (e.g. an array of pairs, a single number, or omits Data entirely). Also reached by an undo replay whose captured Data was serialized differently.
Common situations: Client-side serialization bug; version skew where an older client uses a different payload schema; a manually crafted HTTP request to the transaction endpoint with a malformed body.
Related errors
- invalid width for attribute view column [%s]
- invalid card aspect ratio preset [%v]
- invalid card aspect ratio [%v]
- at least one visible view is required
- view [%s] not found in attribute view [%s]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/e9d21e67b5521114.
Report an issue: GitHub.