wavetermdev/waveterm · error

error finding tab: %v

Error message

error finding tab: %v

What it means

When resolving the 'tab' simple id, resolveThis finds the tab that contains the request's block via wstore.DBFindTabForBlockId. This error wraps a failure of that lookup — the tab containing the given blockId could not be found or the store lookup errored. It indicates an inconsistent block reference or store access problem.

Source

Thrown at pkg/wshrpc/wshserver/resolvers.go:93

		return "uuid8", simpleId, nil
	}

	return "", "", fmt.Errorf("invalid simple id format: %s", simpleId)
}

// Individual resolvers
func resolveThis(ctx context.Context, data wshrpc.CommandResolveIdsData, value string) (*waveobj.ORef, error) {
	if data.BlockId == "" {
		return nil, fmt.Errorf("no blockid in request")
	}

	if value == SimpleId_This || value == SimpleId_Block {
		return &waveobj.ORef{OType: waveobj.OType_Block, OID: data.BlockId}, nil
	}
	if value == SimpleId_Tab {
		tabId, err := wstore.DBFindTabForBlockId(ctx, data.BlockId)
		if err != nil {
			return nil, fmt.Errorf("error finding tab: %v", err)
		}
		return &waveobj.ORef{OType: waveobj.OType_Tab, OID: tabId}, nil
	}
	if value == SimpleId_Ws || value == SimpleId_Workspace {
		tabId, err := wstore.DBFindTabForBlockId(ctx, data.BlockId)
		if err != nil {
			return nil, fmt.Errorf("error finding tab: %v", err)
		}
		wsId, err := wstore.DBFindWorkspaceForTabId(ctx, tabId)
		if err != nil {
			return nil, fmt.Errorf("error finding workspace: %v", err)
		}
		return &waveobj.ORef{OType: waveobj.OType_Workspace, OID: wsId}, nil
	}
	if value == SimpleId_Client || value == SimpleId_Global {
		clientId := wstore.GetClientId()
		return &waveobj.ORef{OType: waveobj.OType_Client, OID: clientId}, nil
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the blockId still exists (BlockInfoCommand or store lookup) before resolving 'tab'.
  2. Refresh workspace/tab state on the client and retry with a current blockId.
  3. Handle NotFound distinctly and fall back to resolving via the workspace's tab list.

Example fix

// before
oref, err := wshclient.ResolveIdsCommand(ctx, wshrpc.CommandResolveIdsData{SimpleId: "tab", BlockId: staleBlockId}, nil)
// after
if _, err := wshclient.BlockInfoCommand(ctx, staleBlockId, nil); err != nil {
    staleBlockId = currentBlockId // refresh from view state
}
oref, err := wshclient.ResolveIdsCommand(ctx, wshrpc.CommandResolveIdsData{SimpleId: "tab", BlockId: staleBlockId}, nil)
Defensive patterns

Strategy: validation

Validate before calling

_, err := wshclient.BlockInfoCommand(ctx, blockId, nil)
if err != nil {
    return fmt.Errorf("block %s gone, cannot resolve 'tab': %w", blockId, err)
}

Type guard

func isNotFound(err error) bool {
    return err != nil && (errors.Is(err, wstore.ErrNotFound) || strings.Contains(err.Error(), "not found"))
}

Try / catch

tabRef, err := wshclient.ResolveIdsCommand(ctx, wshrpc.CommandResolveIdsData{SimpleId: "tab", BlockId: blockId}, nil)
if err != nil && isNotFound(err) {
    tabRef = resolveTabFromCurrentWorkspace(blockId) // fallback path
}

Prevention

When it happens

Trigger: Calling ResolveIds with simpleId 'tab' where data.BlockId refers to a block that no longer exists, was deleted concurrently, or the wstore lookup returns an error (record missing / DB failure).

Common situations: Stale frontend state after a block was closed; resolving ids for blocks in a tab that was just removed; race between block deletion and id resolution; corrupted or out-of-sync local store.

Related errors


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