wavetermdev/waveterm · error

blockid is required

Error message

blockid is required

What it means

DebugTermCommand dumps the tail of a block's terminal debug file via WFS. It rejects the call up front when the required BlockId field of CommandDebugTermData is empty, since it cannot locate the term file without it.

Source

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

	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
}

func (ws *WshServer) DebugTermCommand(ctx context.Context, data wshrpc.CommandDebugTermData) (*wshrpc.CommandDebugTermRtnData, error) {
	if data.BlockId == "" {
		return nil, fmt.Errorf("blockid is required")
	}
	if data.Size <= 0 {
		return nil, fmt.Errorf("size must be greater than 0")
	}
	waveFile, err := filestore.WFS.Stat(ctx, data.BlockId, wavebase.BlockFile_Term)
	if err == fs.ErrNotExist {
		return &wshrpc.CommandDebugTermRtnData{}, nil
	}
	if err != nil {
		return nil, fmt.Errorf("error statting term file: %w", err)
	}
	readSize := data.Size
	dataLength := waveFile.DataLength()
	if readSize > dataLength {
		readSize = dataLength
	}
	readOffset := waveFile.Size - readSize
	readOffset, readData, err := filestore.WFS.ReadAt(ctx, data.BlockId, wavebase.BlockFile_Term, readOffset, readSize)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set CommandDebugTermData.BlockId to the target block's OID before invoking the RPC
  2. Verify the block exists (wsh blocks list or wstore lookup) and copy its ID into the request
  3. Check that the client-side JSON payload actually serializes blockid (field not accidentally empty)

Example fix

// before
resp, err := client.DebugTermCommand(ctx, wshrpc.CommandDebugTermData{Size: 1024})
// after
resp, err := client.DebugTermCommand(ctx, wshrpc.CommandDebugTermData{BlockId: blockId, Size: 1024})
Defensive patterns

Strategy: validation

Validate before calling

if data.BlockId == "" {
    return fmt.Errorf("cannot call DebugTermCommand: BlockId is empty")
}

Type guard

func hasBlockId(data wshrpc.CommandDebugTermData) bool {
    return data.BlockId != ""
}

Try / catch

resp, err := client.DebugTermCommand(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "blockid is required") {
        // fix payload: set BlockId
    }
    return err
}

Prevention

When it happens

Trigger: Calling wsh rpc DebugTermCommand with a CommandDebugTermData where BlockId is "" (zero value, never set).

Common situations: Scripts building the RPC payload programmatically and forgetting to fill BlockId; callers using a default-constructed struct; deserialization dropping the field when the client omits it in JSON.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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