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
- Verify the blockId exists via wstore.DBGet[*waveobj.Block] before resyncing
- Remove or skip stale block references on the caller side (clear cached block lists on restart)
- Handle block deletion events to drop pending resync requests
- 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
- Prune stale block references from frontend state on restart
- Subscribe to block-deletion events and drop pending resyncs
- Confirm blockId against wstore before resync calls
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
- parent block not found: %q
- error getting client: %v
- invalid tabId or blockId passed to ResyncController
- unknown controller type %q
- error starting controller: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/98e25f8dd2230dc8.
Report an issue: GitHub.