wavetermdev/waveterm · error

blockDef is nil

Error message

blockDef is nil

What it means

CreateSubBlock rejects a nil BlockDef up front. The RPC command CreateSubBlockCommand passes the caller-supplied block definition straight through, so a null definition reaches the core without any view, metadata, or files to create a block from.

Source

Thrown at pkg/wcore/block.go:26

	"fmt"
	"log"
	"time"

	"github.com/google/uuid"
	"github.com/wavetermdev/waveterm/pkg/filestore"
	"github.com/wavetermdev/waveterm/pkg/panichandler"
	"github.com/wavetermdev/waveterm/pkg/telemetry"
	"github.com/wavetermdev/waveterm/pkg/telemetry/telemetrydata"
	"github.com/wavetermdev/waveterm/pkg/util/utilfn"
	"github.com/wavetermdev/waveterm/pkg/waveobj"
	"github.com/wavetermdev/waveterm/pkg/wps"
	"github.com/wavetermdev/waveterm/pkg/wshrpc"
	"github.com/wavetermdev/waveterm/pkg/wstore"
)

func CreateSubBlock(ctx context.Context, blockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) {
	if blockDef == nil {
		return nil, fmt.Errorf("blockDef is nil")
	}
	if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" {
		return nil, fmt.Errorf("no view provided for new block")
	}
	blockData, err := createSubBlockObj(ctx, blockId, blockDef)
	if err != nil {
		return nil, fmt.Errorf("error creating sub block: %w", err)
	}
	blockView := blockDef.Meta.GetString(waveobj.MetaKey_View, "")
	blockController := blockDef.Meta.GetString(waveobj.MetaKey_Controller, "")
	go recordBlockCreationTelemetry(blockView, blockController, true)
	return blockData, nil
}

func createSubBlockObj(ctx context.Context, parentBlockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) {
	return wstore.WithTxRtn(ctx, func(tx *wstore.TxWrap) (*waveobj.Block, error) {
		parentBlock, _ := wstore.DBGet[*waveobj.Block](tx.Context(), parentBlockId)
		if parentBlock == nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Always construct and pass a full waveobj.BlockDef with a Meta map containing MetaKey_View
  2. In the calling command handler, check the parsed argument for nil before invoking CreateSubBlock
  3. If the definition comes from external input, unmarshal and validate it before the RPC call

Example fix

// before
block, err := wcore.CreateSubBlock(ctx, blockId, nil)
// after
blockDef := &waveobj.BlockDef{Meta: waveobj.MetaMapType{waveobj.MetaKey_View: "term"}}
block, err := wcore.CreateSubBlock(ctx, blockId, blockDef)
Defensive patterns

Strategy: validation

Validate before calling

if blockDef == nil {
    return nil, errors.New("caller bug: blockDef must be provided")
}

Type guard

func hasBlockDef(d *waveobj.BlockDef) bool { return d != nil }

Try / catch

block, err := wcore.CreateSubBlock(ctx, blockId, blockDef)
if err != nil && err.Error() == "blockDef is nil" {
    // construct a valid BlockDef and retry
}

Prevention

When it happens

Trigger: Calling CreateSubBlock / CreateSubBlockCommand with blockDef == nil, e.g. a client RPC payload where the blockdef field was omitted or deserialized to null.

Common situations: Scripts or frontend code calling the wsh create-subblock RPC without a body; an automation tool sending a partially-built command object.

Related errors


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