wavetermdev/waveterm · error

error getting block: %w

Error message

error getting block: %w

What it means

BlockInfoCommand assembles metadata for a block: its record, containing tab, workspace/window, and blockfile list. This error wraps a failure of wstore.DBMustGet[*waveobj.Block] — the given blockId does not correspond to an existing block record (or the store lookup failed). Nothing else in the command runs.

Source

Thrown at pkg/wshrpc/wshserver/wshserver.go:809

	return shellutil.FindGitBash(&fullConfig, rescan), nil
}

func waveFileToWaveFileInfo(wf *filestore.WaveFile) *wshrpc.WaveFileInfo {
	return &wshrpc.WaveFileInfo{
		ZoneId:    wf.ZoneId,
		Name:      wf.Name,
		Opts:      wf.Opts,
		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{

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the blockId exists and is a block-type oid before calling.
  2. Refresh block references from the workspace/tab state and retry.
  3. Handle the wrapped NotFound by cleaning up stale UI state referencing the block.
  4. Check for type mismatches: the oid must be for a Block, not a tab/workspace.

Example fix

// before
info, err := wshclient.BlockInfoCommand(ctx, staleBlockId, nil)
// after
info, err := wshclient.BlockInfoCommand(ctx, currentBlockId, nil)
if err != nil && strings.Contains(err.Error(), "error getting block") {
    // remove stale block from UI state
}
Defensive patterns

Strategy: validation

Validate before calling

if blockId == "" {
    return errors.New("blockId required")
}
// ensure the oid is a block ref
if _, err := waveobj.ParseORef("block:" + blockId); err != nil {
    return err
}

Type guard

func isBlockGone(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error getting block")
}

Try / catch

info, err := wshclient.BlockInfoCommand(ctx, blockId, nil)
if err != nil {
    if isBlockGone(err) {
        removeStaleBlockFromState(blockId)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling BlockInfoCommand with a blockId that was deleted, never existed, or a malformed id; the store returns NotFound or a DB error.

Common situations: Frontend holding a stale blockId after the block was closed; caller passing an oid of a non-block object type; race with tab/workspace removal; typos when scripting against the RPC.

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


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