{"record":{"id":"8fb04dc34c629de1","repo":"wavetermdev/waveterm","slug":"error-creating-sub-block-w","errorCode":null,"errorMessage":"error creating sub block: %w","messagePattern":"error creating sub block: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/block.go","lineNumber":33,"sourceCode":"\t\"github.com/wavetermdev/waveterm/pkg/telemetry\"\n\t\"github.com/wavetermdev/waveterm/pkg/telemetry/telemetrydata\"\n\t\"github.com/wavetermdev/waveterm/pkg/util/utilfn\"\n\t\"github.com/wavetermdev/waveterm/pkg/waveobj\"\n\t\"github.com/wavetermdev/waveterm/pkg/wps\"\n\t\"github.com/wavetermdev/waveterm/pkg/wshrpc\"\n\t\"github.com/wavetermdev/waveterm/pkg/wstore\"\n)\n\nfunc CreateSubBlock(ctx context.Context, blockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) {\n\tif blockDef == nil {\n\t\treturn nil, fmt.Errorf(\"blockDef is nil\")\n\t}\n\tif blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, \"\") == \"\" {\n\t\treturn nil, fmt.Errorf(\"no view provided for new block\")\n\t}\n\tblockData, err := createSubBlockObj(ctx, blockId, blockDef)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating sub block: %w\", err)\n\t}\n\tblockView := blockDef.Meta.GetString(waveobj.MetaKey_View, \"\")\n\tblockController := blockDef.Meta.GetString(waveobj.MetaKey_Controller, \"\")\n\tgo recordBlockCreationTelemetry(blockView, blockController, true)\n\treturn blockData, nil\n}\n\nfunc createSubBlockObj(ctx context.Context, parentBlockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) {\n\treturn wstore.WithTxRtn(ctx, func(tx *wstore.TxWrap) (*waveobj.Block, error) {\n\t\tparentBlock, _ := wstore.DBGet[*waveobj.Block](tx.Context(), parentBlockId)\n\t\tif parentBlock == nil {\n\t\t\treturn nil, fmt.Errorf(\"parent block not found: %q\", parentBlockId)\n\t\t}\n\t\tblockId := uuid.NewString()\n\t\tblockData := &waveobj.Block{\n\t\t\tOID:         blockId,\n\t\t\tParentORef:  waveobj.MakeORef(waveobj.OType_Block, parentBlockId).String(),\n\t\t\tRuntimeOpts: nil,","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/block.go#L15-L51","documentation":"This wraps any failure from the internal createSubBlockObj, which runs in a DB transaction (wstore.WithTxRtn) to create the block object and attach it to the parent block. It is a wrapper error; the real cause is the %w-wrapped inner error.","triggerScenarios":"CreateSubBlock called with a valid blockDef but createSubBlockObj fails: parent block missing, database/transaction error, or constraint failure while persisting the new block.","commonSituations":"Referencing a stale or deleted parent blockId; SQLite store locked or corrupted; concurrent modification of the parent block.","solutions":["Inspect the wrapped inner error to identify the root cause","Verify the parent blockId exists and has not been deleted","Retry after resolving DB issues (lock contention, disk space)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"parent, _ := wstore.DBGet[*waveobj.Block](ctx, parentBlockId)\nif parent == nil { return errors.New(\"parent missing, aborting\") }","typeGuard":null,"tryCatchPattern":"block, err := wcore.CreateSubBlock(ctx, blockId, blockDef)\nif err != nil {\n    var wrapped string = err.Error() // contains inner cause via %w\n    if errors.Is(err, someDBErr) { /* retry/backoff */ }\n}","preventionTips":["Unwrap with errors.Is/As to find the root cause","Confirm parent block exists before creating sub-blocks","Monitor SQLite health (locks, disk space)"],"tags":["database","blocks","wrapped-error"],"backgroundTag":"wrapped-root-cause-error","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}