wavetermdev/waveterm · error

error getting block: %w

Error message

error getting block: %w

What it means

ResyncController fetches the block record from wstore with DBMustGet before resolving its controller. If the block does not exist (or the DB read fails), the error is wrapped as 'error getting block: %w'. This means resync was requested for a blockId the store does not know about.

Source

Thrown at pkg/blockcontroller/blockcontroller.go:162

		return
	}
	go DestroyBlockController(blockId)
}

// Public API Functions

func ResyncController(ctx context.Context, tabId string, blockId string, rtOpts *waveobj.RuntimeOpts, force bool) error {
	if tabId == "" || blockId == "" {
		return fmt.Errorf("invalid tabId or blockId passed to ResyncController")
	}

	mu := getBlockResyncMutex(blockId)
	mu.Lock()
	defer mu.Unlock()

	blockData, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId)
	if err != nil {
		return fmt.Errorf("error getting block: %w", err)
	}

	controllerName := blockData.Meta.GetString(waveobj.MetaKey_Controller, "")
	connName := blockData.Meta.GetString(waveobj.MetaKey_Connection, "")

	// Get existing controller
	existing := getController(blockId)

	// Check for connection change FIRST - always destroy on conn change
	if existing != nil {
		existingConnName := existing.GetConnName()
		if existingConnName != connName {
			log.Printf("stopping blockcontroller %s due to conn change (from %q to %q)\n", blockId, existingConnName, connName)
			DestroyBlockController(blockId)
			time.Sleep(100 * time.Millisecond)
			existing = nil
		}
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the blockId exists via wstore.DBGet[*waveobj.Block] before resyncing
  2. Remove or skip stale block references on the caller side (clear cached block lists on restart)
  3. Handle block deletion events to drop pending resync requests
  4. If the block should exist, check the wstore DB file integrity/location

Example fix

// before
ResyncController(ctx, tabId, staleBlockId, nil, false)
// after
if _, err := wstore.DBGet[*waveobj.Block](ctx, blockId); err != nil {
    return // block gone; skip resync
}
ResyncController(ctx, tabId, blockId, nil, false)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := wstore.DBGet[*waveobj.Block](ctx, blockId); err != nil {
    // block missing: skip resync
}

Try / catch

if err := ResyncController(ctx, tabId, blockId, nil, false); err != nil {
    var notFound bool
    if strings.Contains(err.Error(), "error getting block") { notFound = true }
    _ = notFound
}

Prevention

When it happens

Trigger: Calling ResyncController with a blockId that has no row in the wstore — a deleted block, a stale ID from a previous session, or a fabricated/typo'd ID.

Common situations: Frontend resyncing a block after it was closed/deleted elsewhere; stale IDs persisted client-side across app restarts; race where block deletion completes before a pending resync executes.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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