{"record":{"id":"ba073d03df11259b","repo":"wavetermdev/waveterm","slug":"error-getting-tab-blocks-w","errorCode":null,"errorMessage":"error getting tab blocks: %w","messagePattern":"error getting tab blocks: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/workspaceservice/workspaceservice.go","lineNumber":189,"sourceCode":"}\n\nfunc (svc *WorkspaceService) SetActiveTab(workspaceId string, tabId string) (waveobj.UpdatesRtnType, error) {\n\tctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)\n\tdefer cancelFn()\n\tctx = waveobj.ContextWithUpdates(ctx)\n\terr := wcore.SetActiveTab(ctx, workspaceId, tabId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error setting active tab: %w\", err)\n\t}\n\t// check all blocks in tab and start controllers (if necessary)\n\ttab, err := wstore.DBMustGet[*waveobj.Tab](ctx, tabId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting tab: %w\", err)\n\t}\n\tblockORefs := tab.GetBlockORefs()\n\tblocks, err := wstore.DBSelectORefs(ctx, blockORefs)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting tab blocks: %w\", err)\n\t}\n\tupdates := waveobj.ContextGetUpdatesRtn(ctx)\n\tgo func() {\n\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(\"WorkspaceService:SetActiveTab:SendUpdateEvents\", recover())\n\t\t}()\n\t\twps.Broker.SendUpdateEvents(updates)\n\t}()\n\tvar extraUpdates waveobj.UpdatesRtnType\n\textraUpdates = append(extraUpdates, updates...)\n\textraUpdates = append(extraUpdates, waveobj.MakeUpdate(tab))\n\textraUpdates = append(extraUpdates, waveobj.MakeUpdates(blocks)...)\n\treturn extraUpdates, nil\n}\n\ntype CloseTabRtnType struct {\n\tCloseWindow    bool   `json:\"closewindow,omitempty\"`\n\tNewActiveTabId string `json:\"newactivetabid,omitempty\"`","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/service/workspaceservice/workspaceservice.go#L171-L207","documentation":"After fetching the tab, SetActiveTab loads all of the tab's block objects via wstore.DBSelectORefs to decide which shell controllers to start. If loading any block reference fails, the error is wrapped as \"error getting tab blocks: %w\". This means the tab exists but one or more of its child block records cannot be read.","triggerScenarios":"A tab whose blockrefs point to blocks that are missing from the DB, or a storage failure during DBSelectORefs, triggered by SetActiveTab on such a tab.","commonSituations":"Partially deleted or corrupted tab state (block rows removed without updating tab.blockrefs), interrupted writes from a crash.","solutions":["Inspect the tab's blockrefs and remove dangling ORefs pointing at missing blocks","Unwrap the error to identify the specific failing block oref","Restore the wave DB from backup if corruption is widespread","Avoid killing the app mid-write to prevent orphaned blockrefs"],"exampleFix":"// before\nblocks, err := wstore.DBSelectORefs(ctx, blockORefs) // some orefs dangling\n// after\nvar valid []waveobj.ORef\nfor _, oref := range blockORefs {\n    if _, err := wstore.DBGet(ctx, oref.OType, oref.OID); err == nil {\n        valid = append(valid, oref)\n    }\n}\nblocks, err := wstore.DBSelectORefs(ctx, valid)","handlingStrategy":"validation","validationCode":"tab, err := wstore.DBGet[*waveobj.Tab](ctx, tabId)\nif err != nil { return err }\nfor _, oref := range tab.GetBlockORefs() {\n    if _, err := wstore.DBGet(ctx, oref.OType, oref.OID); err != nil {\n        return fmt.Errorf(\"dangling block ref %s: %w\", oref, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"_, err := svc.SetActiveTab(workspaceId, tabId)\nif err != nil {\n    var dbErr *wstore.ErrDB\n    if errors.As(errors.Unwrap(err), &dbErr) { /* repair blockrefs */ }\n    return err\n}","preventionTips":["Ensure tab deletion also cleans block rows atomically","Periodically verify blockrefs resolve to real blocks","Never kill the app during DB writes"],"tags":["go","workspace","blocks","database"],"backgroundTag":"wrapped-error-propagation","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}