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
- Always construct and pass a full waveobj.BlockDef with a Meta map containing MetaKey_View
- In the calling command handler, check the parsed argument for nil before invoking CreateSubBlock
- 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
- Never pass nullable blockdef values straight from RPC payloads into core APIs
- Validate RPC command arguments before dispatching
- Use constructors/helpers that always produce a complete BlockDef
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
- no WAVETERM_TABID env var set
- create block failed: %v
- no WAVETERM_TABID env var set
- running view command: %w
- no WAVETERM_TABID env var set
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2e921afd9630f0bd.
Report an issue: GitHub.