wavetermdev/waveterm · error
error getting tab: %w
Error message
error getting tab: %w
What it means
GetTab wraps any failure from wstore.DBGet[*waveobj.Tab] with 'error getting tab: %w'. It is thrown when the tab lookup in the wstore database fails — most often because no Tab object exists for the given tabId, or the underlying DB read errored. The wrapped error is preserved so callers can inspect the root cause (e.g. 'key not found').
Source
Thrown at pkg/service/clientservice/clientservice.go:37
)
type ClientService struct{}
const DefaultTimeout = 2 * time.Second
func (cs *ClientService) GetClientData() (*waveobj.Client, error) {
log.Println("GetClientData")
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
return wcore.GetClientData(ctx)
}
func (cs *ClientService) GetTab(tabId string) (*waveobj.Tab, error) {
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
tab, err := wstore.DBGet[*waveobj.Tab](ctx, tabId)
if err != nil {
return nil, fmt.Errorf("error getting tab: %w", err)
}
return tab, nil
}
func (cs *ClientService) GetAllConnStatus(ctx context.Context) ([]wshrpc.ConnStatus, error) {
sshStatuses := conncontroller.GetAllConnStatus()
wslStatuses := wslconn.GetAllConnStatus()
return append(sshStatuses, wslStatuses...), nil
}
// moves the window to the front of the windowId stack
func (cs *ClientService) FocusWindow(ctx context.Context, windowId string) error {
return wcore.FocusWindow(ctx, windowId)
}
func (cs *ClientService) AgreeTos(ctx context.Context) (waveobj.UpdatesRtnType, error) {
ctx = waveobj.ContextWithUpdates(ctx)
clientData, err := wstore.DBGetSingleton[*waveobj.Client](ctx)View on GitHub (pinned to a4447c1563)
Solutions
- Verify the tabId exists (check it came from a current window/tab list, not a stale cache)
- Check the wrapped error: if 'key not found', treat the tab as deleted and refresh the tab list
- If DB errors persist, inspect the wstore DB file for corruption/permissions
Example fix
// before
tab, err := cs.GetTab(staleTabId)
// after
tab, err := cs.GetTab(tabId)
if err != nil && strings.Contains(err.Error(), "key not found") {
tab, err = cs.GetTab(currentTabId) // re-resolve from active window
} Defensive patterns
Strategy: try-catch
Validate before calling
if tabId == "" { return fmt.Errorf("tabId required") } Type guard
func hasTabId(tabId string) bool { return strings.TrimSpace(tabId) != "" } Try / catch
tab, err := cs.GetTab(tabId)
if err != nil {
if strings.Contains(err.Error(), "key not found") { /* tab deleted; refresh list */ }
return err
} Prevention
- Obtain tabIds from live tab listings, never long-lived caches
- Distinguish tabId from blockId/windowId at call sites
- Treat 'key not found' as an expected outcome and handle idempotently
When it happens
Trigger: Calling ClientService.GetTab with a tabId that was deleted, a typo'd/stale tabId from a cached reference, or when the wstore DB read fails (IO/corruption).
Common situations: Frontend holds a tabId after the tab was closed in another window; restoring workspace state referencing removed tabs; passing a blockId or windowId instead of a tabId.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- error getting client data: %w
- error getting object: %w
- error updating %q meta: %w
- error getting tab: %w
- error creating tab: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/08a469f44210ac15.
Report an issue: GitHub.