wavetermdev/waveterm · error
error getting tab: %w
Error message
error getting tab: %w
What it means
After switching the active tab, SetActiveTab fetches the Tab object with wstore.DBMustGet[*waveobj.Tab] to enumerate its blocks. If that fetch fails, the error is wrapped as "error getting tab: %w". Notably this can occur even though SetActiveTab succeeded, meaning the tabId exists for activation but could not be read from the store.
Source
Thrown at pkg/service/workspaceservice/workspaceservice.go:184
func (svc *WorkspaceService) SetActiveTab_Meta() tsgenmeta.MethodMeta {
return tsgenmeta.MethodMeta{
ArgNames: []string{"workspaceId", "tabId"},
}
}
func (svc *WorkspaceService) SetActiveTab(workspaceId string, tabId string) (waveobj.UpdatesRtnType, error) {
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
ctx = waveobj.ContextWithUpdates(ctx)
err := wcore.SetActiveTab(ctx, workspaceId, tabId)
if err != nil {
return nil, fmt.Errorf("error setting active tab: %w", err)
}
// check all blocks in tab and start controllers (if necessary)
tab, err := wstore.DBMustGet[*waveobj.Tab](ctx, tabId)
if err != nil {
return nil, fmt.Errorf("error getting tab: %w", err)
}
blockORefs := tab.GetBlockORefs()
blocks, err := wstore.DBSelectORefs(ctx, blockORefs)
if err != nil {
return nil, fmt.Errorf("error getting tab blocks: %w", err)
}
updates := waveobj.ContextGetUpdatesRtn(ctx)
go func() {
defer func() {
panichandler.PanicHandler("WorkspaceService:SetActiveTab:SendUpdateEvents", recover())
}()
wps.Broker.SendUpdateEvents(updates)
}()
var extraUpdates waveobj.UpdatesRtnType
extraUpdates = append(extraUpdates, updates...)
extraUpdates = append(extraUpdates, waveobj.MakeUpdate(tab))
extraUpdates = append(extraUpdates, waveobj.MakeUpdates(blocks)...)
return extraUpdates, nilView on GitHub (pinned to a4447c1563)
Solutions
- Unwrap the error to distinguish not-found from I/O failure
- Re-fetch workspace state and retry SetActiveTab with a valid tabId
- Check for concurrent CloseTab/DeleteTab races against the same tabId
- Verify DB integrity
Example fix
// before
_, err = wsSvc.SetActiveTab(wsId, tabId) // error getting tab
// after
tab, err := wstore.DBGet[*waveobj.Tab](ctx, tabId)
if err == nil {
_, err = wsSvc.SetActiveTab(wsId, tabId)
} Defensive patterns
Strategy: validation
Validate before calling
if _, err := wstore.DBGet[*waveobj.Tab](ctx, tabId); err != nil {
return fmt.Errorf("tab %s unreadable, cannot activate: %w", tabId, err)
}
_, err = svc.SetActiveTab(workspaceId, tabId) Try / catch
rtn, err := svc.SetActiveTab(workspaceId, tabId)
if err != nil {
if strings.Contains(err.Error(), "error getting tab") { /* DB read failure path */ }
return err
} Prevention
- Avoid deleting tabs while another caller activates them
- Monitor DB health; DBMustGet failures usually mean missing rows
- Re-sync client state after any not-found error
When it happens
Trigger: Calling SetActiveTab with a tabId that is set as active but missing/deleted in the DB (DBMustGet panics-free path returns error), or a storage failure reading the Tab object.
Common situations: Race condition where the tab is deleted between the SetActiveTab core call and the DBMustGet; DB corruption; stale tab id.
Related errors
- error getting tab: %w
- error creating tab: %w
- error setting active tab: %w
- error getting tab blocks: %w
- error closing tab: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/b736ea6d3f7321ef.
Report an issue: GitHub.