{"record":{"id":"6b57ac5f762aa2fc","repo":"siyuan-note/siyuan","slug":"wrong-layout-type","errorCode":null,"errorMessage":"wrong layout type","messagePattern":"wrong layout type","errorType":"http","errorClass":"ErrWrongLayoutType","httpStatus":null,"severity":"error","filePath":"kernel/av/av.go","lineNumber":1299,"sourceCode":"\t\t\tlogging.LogErrorf(\"create attribute view dir failed: %s\", err)\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\nfunc GetAttributeViewI18n(key string) string {\n\treturn util.AttrViewLangs[util.Lang][key].(string)\n}\n\nvar (\n\tErrAttributeViewNotFound  = errors.New(\"attribute view not found\")\n\tErrInvalidAttributeViewID = errors.New(\"invalid attribute view id\")\n\tErrInvalidBoxID           = errors.New(\"invalid box id\")\n\tErrViewNotFound           = errors.New(\"view not found\")\n\tErrKeyNotFound            = errors.New(\"key not found\")\n\tErrItemNotFound           = errors.New(\"item not found\")\n\tErrWrongLayoutType        = errors.New(\"wrong layout type\")\n\tErrInvalidColumnAlign     = errors.New(\"invalid column align\")\n\tErrSpecTooNew             = errors.New(\"attribute view spec is too new\")\n\tErrFilterTooDeep          = errors.New(\"filter nesting depth exceeds the maximum allowed\")\n)\n\nconst (\n\tNodeAttrNameAvs        = \"custom-avs\"                 // 用于标记块所属的属性视图，逗号分隔 av id\n\tNodeAttrView           = \"custom-sy-av-view\"          // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443\n\tNodeAttrVisibleViewIDs = \"custom-sy-av-visible-views\" // 用于标记数据库块显示的视图 ID，逗号分隔\n\tNodeAttrViewStaticText = \"custom-sy-av-s-text\"        // 用于标记块所属的属性视图静态文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049\n\n\tNodeAttrViewNames = \"av-names\" // 用于临时标记块所属的属性视图名称，空格分隔\n)\n","sourceCodeStart":1281,"sourceCodeEnd":1313,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/av/av.go#L1281-L1313","documentation":"ErrWrongLayoutType is the sentinel error for unsupported or mismatched view layouts in the SiYuan attribute-view engine. Only LayoutTypeTable, LayoutTypeGallery, and LayoutTypeKanban are valid (see the switch in kernel/model/attribute_view_create.go:62-68 and changeAttrViewLayout at kernel/model/attribute_view.go:1388-1396); layout-specific operations additionally require the view to actually be of that layout (kernel/model/attribute_view.go:1977 for card-cover ops).","triggerScenarios":"createAttributeView with a layout string outside table/gallery/kanban; a setAttrViewLayouts/changeLayout operation passing an unknown LayoutType; calling cover-related operations (setAttrViewColCardCover or similar, kernel/model/attribute_view.go:1789, 1837, 1977, 4996) on a view whose LayoutType is table instead of gallery/kanban.","commonSituations":"A plugin forwards a raw layout string from user input or an older API payload; code written against a fork that added layouts (e.g. a list/calendar layout) runs against mainline; a kanban-only feature is invoked on a table view because the viewID resolved to the wrong view.","solutions":["Normalize the layout before calling: default to av.LayoutTypeTable when the input is empty and reject anything not in {table, gallery, kanban}","Verify view.LayoutType matches the operation's requirement (gallery/kanban for cover settings) before dispatching","If you need another layout, check the installed SiYuan version's supported set instead of assuming; upgrade both kernel and frontend together","Inspect the exact LayoutType via view.GetType() from a fresh render response"],"exampleFix":"// before\nview, err := model.CreateAttributeView(name, av.LayoutType(hookedLayout), cols)\n\n// after\nvar layout av.LayoutType\nswitch hookedLayout {\ncase av.LayoutTypeTable, av.LayoutTypeGallery, av.LayoutTypeKanban:\n    layout = hookedLayout\ndefault:\n    layout = av.LayoutTypeTable\n}\nview, err := model.CreateAttributeView(name, layout, cols)","handlingStrategy":"validation","validationCode":"func isSupportedLayout(l av.LayoutType) bool {\n    switch l {\n    case av.LayoutTypeTable, av.LayoutTypeGallery, av.LayoutTypeKanban:\n        return true\n    }\n    return false\n}\n// and for cover ops:\nif view.LayoutType != av.LayoutTypeGallery && view.LayoutType != av.LayoutTypeKanban {\n    return nil // cover settings only apply to card layouts\n}","typeGuard":"func isWrongLayoutType(err error) bool {\n    return errors.Is(err, av.ErrWrongLayoutType)\n}","tryCatchPattern":"if err := changeLayout(tx, view, newLayout); errors.Is(err, av.ErrWrongLayoutType) {\n    // clamp to table and inform the user the layout is unsupported in this version\n}","preventionTips":["Expose only table/gallery/kanban in your UI's layout picker unless the kernel constants say otherwise","Check view.GetType() from the render payload before invoking layout-specific operations","Version-check plugins that rely on layout features before dispatching"],"tags":["siyuan","attribute-view","layout","validation","go"],"backgroundTag":"type-layout-unsupported-type","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}