wavetermdev/waveterm · error
error finding window for tab: %w
Error message
error finding window for tab: %w
What it means
BlockInfoCommand walks up the hierarchy: block -> tab -> workspace (labeled 'window' in this message, for historical reasons). This error wraps failure of wstore.DBFindWorkspaceForTabId — the tab exists but no workspace containing it could be found or the lookup errored. It indicates a broken tab-to-workspace link.
Source
Thrown at pkg/wshrpc/wshserver/wshserver.go:817
CreatedTs: wf.CreatedTs,
Size: wf.Size,
ModTs: wf.ModTs,
Meta: wf.Meta,
}
}
func (ws *WshServer) BlockInfoCommand(ctx context.Context, blockId string) (*wshrpc.BlockInfoData, error) {
blockData, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId)
if err != nil {
return nil, fmt.Errorf("error getting block: %w", err)
}
tabId, err := wstore.DBFindTabForBlockId(ctx, blockId)
if err != nil {
return nil, fmt.Errorf("error finding tab for block: %w", err)
}
workspaceId, err := wstore.DBFindWorkspaceForTabId(ctx, tabId)
if err != nil {
return nil, fmt.Errorf("error finding window for tab: %w", err)
}
fileList, err := filestore.WFS.ListFiles(ctx, blockId)
if err != nil {
return nil, fmt.Errorf("error listing blockfiles: %w", err)
}
var fileInfoList []*wshrpc.WaveFileInfo
for _, wf := range fileList {
fileInfoList = append(fileInfoList, waveFileToWaveFileInfo(wf))
}
return &wshrpc.BlockInfoData{
BlockId: blockId,
TabId: tabId,
WorkspaceId: workspaceId,
Block: blockData,
Files: fileInfoList,
}, nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Reload workspace state to rebuild the tab->workspace mapping and retry.
- If the tab is orphaned, close/remove it or reassign it to an existing workspace.
- Inspect the wrapped cause to separate NotFound from a genuine DB error.
- Re-run after store consistency is restored (restart app or repair store).
Example fix
// before
info, err := wshclient.BlockInfoCommand(ctx, blockId, nil) // workspace gone
// after
if _, err := wshclient.BlockInfoCommand(ctx, blockId, nil); err != nil {
workspaceId = ensureTabInWorkspace(currentTabId, defaultWorkspaceId) // reattach tab first
}
_ = workspaceId Defensive patterns
Strategy: fallback
Validate before calling
wsId := getWorkspaceIdForTabFromLocalState(tabId)
if wsId == "" {
return errors.New("tab has no workspace; refusing BlockInfoCommand")
} Type guard
func isOrphanedTab(err error) bool {
return err != nil && strings.Contains(err.Error(), "error finding window for tab")
} Try / catch
info, err := wshclient.BlockInfoCommand(ctx, blockId, nil)
if err != nil && isOrphanedTab(err) {
// reattach tab to a default workspace, then retry
_ = wshclient.SetTabWorkspace(ctx, tabId, defaultWsId, nil)
info, err = wshclient.BlockInfoCommand(ctx, blockId, nil)
} Prevention
- Remove tabs with their workspace atomically
- Reload workspace state after restore/migration
- Keep tab->workspace links verified on app start
- Handle the 'window' naming: this step resolves the workspace
When it happens
Trigger: Calling BlockInfoCommand where data's tabId has no parent workspace: orphaned tab record after workspace deletion, workspace id corruption, or a store lookup failure.
Common situations: Workspace deleted while tabs from it still referenced; migration/restore of store data missing the workspace entry; concurrent workspace removal racing the command.
Related errors
- error creating tab: %w
- error setting active tab: %w
- error getting tab: %w
- error closing tab: %w
- error finding tab for block: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/1e2aa70d56845b31.
Report an issue: GitHub.