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

  1. Reload workspace state to rebuild the tab->workspace mapping and retry.
  2. If the tab is orphaned, close/remove it or reassign it to an existing workspace.
  3. Inspect the wrapped cause to separate NotFound from a genuine DB error.
  4. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/1e2aa70d56845b31. Report an issue: GitHub.