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

  1. Inspect the wrapped cause (%w) to identify the underlying DB/IO failure.
  2. Retry the delete after the store is healthy; DeleteBlock is idempotent for missing blocks.
  3. Repair/rebuild the waveworks store if the block record is corrupt.
  4. 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

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


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