{"record":{"id":"0b16cfe5a5afe8d4","repo":"wavetermdev/waveterm","slug":"unable-to-create-block-to-apply-portable-layout-to","errorCode":null,"errorMessage":"unable to create block to apply portable layout to tab %s: %w","messagePattern":"unable to create block to apply portable layout to tab (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/layout.go","lineNumber":124,"sourceCode":"\nfunc QueueLayoutActionForTab(ctx context.Context, tabId string, actions ...waveobj.LayoutActionData) error {\n\tlayoutStateId, err := GetLayoutIdForTab(ctx, tabId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn QueueLayoutAction(ctx, layoutStateId, actions...)\n}\n\nfunc ApplyPortableLayout(ctx context.Context, tabId string, layout PortableLayout, recordTelemetry bool) error {\n\tactions := make([]waveobj.LayoutActionData, len(layout)+1)\n\tactions[0] = waveobj.LayoutActionData{ActionType: LayoutActionDataType_ClearTree}\n\tfor i := 0; i < len(layout); i++ {\n\t\tlayoutAction := layout[i]\n\n\t\tblockData, err := CreateBlockWithTelemetry(ctx, tabId, layoutAction.BlockDef, &waveobj.RuntimeOpts{}, recordTelemetry)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to create block to apply portable layout to tab %s: %w\", tabId, err)\n\t\t}\n\n\t\tactions[i+1] = waveobj.LayoutActionData{\n\t\t\tActionType: LayoutActionDataType_InsertAtIndex,\n\t\t\tBlockId:    blockData.OID,\n\t\t\tIndexArr:   &layoutAction.IndexArr,\n\t\t\tNodeSize:   layoutAction.Size,\n\t\t\tFocused:    layoutAction.Focused,\n\t\t}\n\t}\n\n\terr := QueueLayoutActionForTab(ctx, tabId, actions...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to queue layout actions for portable layout: %w\", err)\n\t}\n\n\treturn nil\n}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/layout.go#L106-L142","documentation":"ApplyPortableLayout materializes each entry of a PortableLayout as a real block (CreateBlockWithTelemetry) before queueing insert actions. This error wraps any block-creation failure for entry i of the layout, including controller spawning or blockdef validation errors from CreateBlock itself.","triggerScenarios":"Applying a layout whose BlockDef has an invalid/unknown view or controller, referencing a missing file (e.g. preview blockdef pointing at a nonexistent path), or CreateBlockWithTelemetry failing because the tab/ctx is invalid.","commonSituations":"A custom or hand-edited layout JSON with a bad blockdef; a preview block pointing at a file that no longer exists; applying a layout to a tabId that no longer exists; invalid meta keys in the block definition.","solutions":["Read the wrapped error from CreateBlockWithTelemetry to find which entry failed","Validate each BlockDef (view/controller keys, file paths) before calling ApplyPortableLayout","Confirm the target tabId exists via GetLayoutIdForTab before applying","Fix the layout definition — correct waveobj.MetaKey values and existing file references"],"exampleFix":"// before\nlayout := PortableLayout{{IndexArr: []int{0}, BlockDef: &waveobj.BlockDef{Meta: waveobj.MetaMapType{\"view\": \"typo\"}}}}\n// after\nlayout := PortableLayout{{IndexArr: []int{0}, BlockDef: &waveobj.BlockDef{Meta: waveobj.MetaMapType{waveobj.MetaKey_View: \"term\"}}}}","handlingStrategy":"validation","validationCode":"for _, la := range layout {\n    if la.BlockDef == nil || la.BlockDef.Meta == nil {\n        return fmt.Errorf(\"layout entry missing blockdef/meta\")\n    }\n    if la.BlockDef.Meta[waveobj.MetaKey_View] == \"\" {\n        return fmt.Errorf(\"layout entry missing view meta\")\n    }\n}","typeGuard":"func validBlockDef(bd *waveobj.BlockDef) bool {\n    return bd != nil && bd.Meta != nil && bd.Meta[waveobj.MetaKey_View] != \"\"\n}","tryCatchPattern":"if err := wcore.ApplyPortableLayout(ctx, tabId, layout, false); err != nil {\n    if strings.Contains(err.Error(), \"unable to create block\") {\n        // log offending layout entries and validate blockdefs\n    }\n}","preventionTips":["Validate every BlockDef (view/controller, file paths) before applying a layout","Only reference files that exist for preview blocks","Confirm the target tab exists before applying"],"tags":["waveterm","layout","blockdef","block-creation"],"backgroundTag":"invalid-block-definition","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}