wavetermdev/waveterm · error
invalid tabId or blockId passed to ResyncController
Error message
invalid tabId or blockId passed to ResyncController
What it means
ResyncController requires both a non-empty tabId and blockId to locate and resync a block's controller. If either identifier is an empty string, the call is rejected immediately before any locking or DB access. This is a guard against callers passing through missing waveobj IDs.
Source
Thrown at pkg/blockcontroller/blockcontroller.go:153
Event: wps.Event_BlockClose,
AllScopes: true,
}, nil)
}
func handleBlockCloseEvent(event *wps.WaveEvent) {
blockId, ok := event.Data.(string)
if !ok {
log.Printf("[blockclose] invalid event data type")
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 changeView on GitHub (pinned to a4447c1563)
Solutions
- Check that the blockId and tabId are non-empty before invoking ResyncController
- Ensure the block was created via wstore and holds valid IDs before requesting resync
- Log the source event to find which caller is sending empty IDs
- Use waveobj.MakeORef parsing helpers to validate incoming orefs before extracting IDs
Example fix
// before
ResyncController(ctx, tabId, "", rtOpts, false)
// after
if tabId == "" || blockId == "" { return }
ResyncController(ctx, tabId, blockId, rtOpts, false) Defensive patterns
Strategy: validation
Validate before calling
func canResync(tabId, blockId string) bool { return tabId != "" && blockId != "" } Try / catch
if err := ResyncController(ctx, tabId, blockId, rtOpts, force); err != nil && strings.Contains(err.Error(), "invalid tabId") {
log.Printf("skipping resync for incomplete ids")
} Prevention
- Validate IDs before issuing resync RPCs
- Skip placeholder/uninitialized blocks in iteration
- Parse orefs and check both IDs are present before dispatching
When it happens
Trigger: Calling ResyncController (directly or via ControllerResyncCommand) with tabId="" or blockId="" — e.g. a resync RPC triggered for a block whose IDs were never set, or an event carrying an uninitialized reference.
Common situations: Frontend sends a resync message for a block before the block was fully created; deserialized event objects with empty ID fields; iterating blocks where a placeholder row has empty IDs.
Related errors
- Image too large (>5MB)
- Unsupported or invalid image type: ${blob.type}
- Invalid CSS color: ${String(color)}
- Invalid CSS color: ${color}
- ai:model is required
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f08bf5ead5273bad.
Report an issue: GitHub.