wavetermdev/waveterm · error
error getting block: %w
Error message
error getting block: %w
What it means
DeleteBlock first fetches the Block by id. If the underlying DB read itself fails (storage error, not merely a nil row) it wraps the failure as "error getting block: %w" and aborts the delete. This distinguishes database-level failures from the benign block==nil case, which returns nil (already deleted).
Source
Thrown at pkg/wcore/block.go:160
ParentORef: waveobj.MakeORef(waveobj.OType_Tab, tabId).String(),
RuntimeOpts: rtOpts,
Meta: blockDef.Meta,
}
wstore.DBInsert(tx.Context(), blockData)
tab.BlockIds = append(tab.BlockIds, blockId)
wstore.DBUpdate(tx.Context(), tab)
return blockData, nil
})
}
// Must delete all blocks individually first.
// Also deletes LayoutState.
// recursive: if true, will recursively close parent tab, window, workspace, if they are empty.
// Returns new active tab id, error.
func DeleteBlock(ctx context.Context, blockId string, recursive bool) error {
block, err := wstore.DBGet[*waveobj.Block](ctx, blockId)
if err != nil {
return fmt.Errorf("error getting block: %w", err)
}
if block == nil {
return nil
}
if len(block.SubBlockIds) > 0 {
for _, subBlockId := range block.SubBlockIds {
err := DeleteBlock(ctx, subBlockId, recursive)
if err != nil {
return fmt.Errorf("error deleting subblock %s: %w", subBlockId, err)
}
}
}
parentBlockCount, err := deleteBlockObj(ctx, blockId)
if err != nil {
return fmt.Errorf("error deleting block: %w", err)
}
log.Printf("DeleteBlock: parentBlockCount: %d", parentBlockCount)
parentORef := waveobj.ParseORefNoErr(block.ParentORef)View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the wrapped cause (%w) to identify the underlying DB/IO failure.
- Retry the delete after the store is healthy; DeleteBlock is idempotent for missing blocks.
- Repair/rebuild the waveworks store if the block record is corrupt.
- Check for concurrent writers/lock contention on the DB file.
Example fix
// before
err := wclient.DeleteBlock(ctx, blockId, false) // opaque failure
// after
if err := wclient.DeleteBlock(ctx, blockId, false); err != nil {
log.Printf("delete failed, cause: %v", errors.Unwrap(err))
} Defensive patterns
Strategy: try-catch
Validate before calling
if blockId == "" { return errors.New("blockId required") } Try / catch
if err := wcore.DeleteBlock(ctx, blockId, false); err != nil {
var cause error
errors.As(err, &cause)
log.Printf("DeleteBlock %s failed: %v (cause: %v)", blockId, err, cause)
return err
} Prevention
- Log errors.Unwrap chains to distinguish storage failures from missing blocks.
- Keep the waveworks DB healthy (clean shutdowns, backup/repair tooling).
- Remember nil block == already deleted; only treat DB errors as failures.
When it happens
Trigger: Calling DeleteBlock / DeleteTab / DeleteBlockCommand when the DBGet on the block store returns a non-nil error — corrupt store, transaction/IO failure, or an underlying waveobj update-layer error while decoding the object.
Common situations: Corrupt or locked local waveworks DB after a crash; concurrent process writing the DB; deserialization issue with a malformed block record.
Related errors
- error deleting subblock %s: %w
- error deleting block: %w
- unable to get layout id for given tab id %s: %w
- error finding workspace for tab to delete %s: %w
- error deleting tab %s: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/1ede841900f19499.
Report an issue: GitHub.