{"record":{"id":"f33c2cc5e6733f00","repo":"wavetermdev/waveterm","slug":"unable-to-get-layout-state-for-given-id-s-w","errorCode":null,"errorMessage":"unable to get layout state for given id %s: %w","messagePattern":"unable to get layout state for given id (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/layout.go","lineNumber":85,"sourceCode":"\t\t\t\twaveobj.MetaKey_View:       \"term\",\n\t\t\t\twaveobj.MetaKey_Controller: \"shell\",\n\t\t\t},\n\t\t}, Focused: true},\n\t}\n}\n\nfunc GetLayoutIdForTab(ctx context.Context, tabId string) (string, error) {\n\ttabObj, err := wstore.DBGet[*waveobj.Tab](ctx, tabId)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to get layout id for given tab id %s: %w\", tabId, err)\n\t}\n\treturn tabObj.LayoutState, nil\n}\n\nfunc QueueLayoutAction(ctx context.Context, layoutStateId string, actions ...waveobj.LayoutActionData) error {\n\tlayoutStateObj, err := wstore.DBGet[*waveobj.LayoutState](ctx, layoutStateId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to get layout state for given id %s: %w\", layoutStateId, err)\n\t}\n\n\tfor i := range actions {\n\t\tif actions[i].ActionId == \"\" {\n\t\t\tactions[i].ActionId = uuid.New().String()\n\t\t}\n\t}\n\n\tif layoutStateObj.PendingBackendActions == nil {\n\t\tlayoutStateObj.PendingBackendActions = &actions\n\t} else {\n\t\t*layoutStateObj.PendingBackendActions = append(*layoutStateObj.PendingBackendActions, actions...)\n\t}\n\n\terr = wstore.DBUpdate(ctx, layoutStateObj)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to update layout state with new actions: %w\", err)\n\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/layout.go#L67-L103","documentation":"QueueLayoutAction looks up a LayoutState object in the wave object store by layoutStateId before appending actions. This error wraps the underlying wstore failure (typically ErrNotFound for a stale/unknown id, or a DB error). It means the layout state referenced by the caller does not exist or is not retrievable.","triggerScenarios":"Calling QueueLayoutAction (directly or via QueueLayoutActionForTab -> GetLayoutIdForTab) with a layoutStateId that is not in the DB, was deleted with its tab, or when the underlying wave store DB read fails (corruption/IO).","commonSituations":"Operating on a tab that was just closed so its LayoutState was removed; passing a tabId instead of a layoutStateId into QueueLayoutAction; racing the initial tab creation so the layout id is stale; disk/DB issues with the wave store.","solutions":["Verify the layoutStateId comes from Tab.LayoutState via GetLayoutIdForTab, not a hand-built or stale id","Confirm the tab still exists and has not been closed/deleted before queueing actions","If using QueueLayoutActionForTab, ensure the tab's LayoutState field is populated (set during tab creation)","Check wstore DB health/file permissions if ErrNotFound is not the wrapped cause"],"exampleFix":"// before\nerr := wcore.QueueLayoutAction(ctx, someCachedId, action)\n// after\nlayoutStateId, err := wcore.GetLayoutIdForTab(ctx, tabId)\nif err != nil { return err }\nerr = wcore.QueueLayoutAction(ctx, layoutStateId, action)","handlingStrategy":"validation","validationCode":"layoutStateId, err := wcore.GetLayoutIdForTab(ctx, tabId)\nif err != nil {\n    // tab or its layout state missing — abort before queueing\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err := wcore.QueueLayoutActionForTab(ctx, tabId, action); err != nil {\n    var nf error\n    if errors.Is(err, wstore.ErrNotFound) || strings.Contains(err.Error(), \"unable to get layout state\") {\n        // re-resolve id or recreate tab layout\n    }\n}","preventionTips":["Always derive layoutStateId from Tab.LayoutState, never cache it across tab close/reopen","Use QueueLayoutActionForTab instead of raw QueueLayoutAction","Check errors.Is(err, wstore.ErrNotFound) to distinguish stale id from DB failure"],"tags":["waveterm","wstore","layout","object-not-found"],"backgroundTag":"record-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}