wavetermdev/waveterm · error
unable to queue layout actions for portable layout: %w
Error message
unable to queue layout actions for portable layout: %w
What it means
After all blocks are created, ApplyPortableLayout queues the clear+insert action sequence via QueueLayoutActionForTab. This error wraps that failure — meaning blocks were created but the layout actions could not be persisted, usually because the tab's LayoutState could not be read or updated (errors 1300/1301 bubbled up wrapped).
Source
Thrown at pkg/wcore/layout.go:138
layoutAction := layout[i]
blockData, err := CreateBlockWithTelemetry(ctx, tabId, layoutAction.BlockDef, &waveobj.RuntimeOpts{}, recordTelemetry)
if err != nil {
return fmt.Errorf("unable to create block to apply portable layout to tab %s: %w", tabId, err)
}
actions[i+1] = waveobj.LayoutActionData{
ActionType: LayoutActionDataType_InsertAtIndex,
BlockId: blockData.OID,
IndexArr: &layoutAction.IndexArr,
NodeSize: layoutAction.Size,
Focused: layoutAction.Focused,
}
}
err := QueueLayoutActionForTab(ctx, tabId, actions...)
if err != nil {
return fmt.Errorf("unable to queue layout actions for portable layout: %w", err)
}
return nil
}
func BootstrapStarterLayout(ctx context.Context) error {
ctx, cancelFn := context.WithTimeout(ctx, 2*time.Second)
defer cancelFn()
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
if err != nil {
log.Printf("unable to find client: %v\n", err)
return fmt.Errorf("unable to find client: %w", err)
}
if len(client.WindowIds) < 1 {
return fmt.Errorf("error bootstrapping layout, no windows exist")
}
View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the wrapped error: if it mentions the tab/layout id, the tab or its LayoutState is missing; if it's a DB error, check storage
- Re-fetch the tab and confirm Tab.LayoutState is non-empty before applying
- Retry the ApplyPortableLayout call; note already-created blocks may remain and a re-run clears the tree first
- Check disk space/permissions for the wstore data directory
Example fix
// before
err := wcore.ApplyPortableLayout(ctx, staleTabId, layout, false)
// after
if _, err := wcore.GetLayoutIdForTab(ctx, tabId); err != nil { return err }
err = wcore.ApplyPortableLayout(ctx, tabId, layout, false) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := wcore.GetLayoutIdForTab(ctx, tabId); err != nil {
return fmt.Errorf("tab %s has no layout state: %w", tabId, err)
} Try / catch
if err := wcore.ApplyPortableLayout(ctx, tabId, layout, false); err != nil {
if strings.Contains(err.Error(), "unable to queue layout actions") {
// tab/layoutstate missing or DB write failed; re-resolve tab and retry
}
} Prevention
- Pre-check the tab and its LayoutState exist
- Handle partial state: blocks may have been created even when queueing fails; re-running clears the tree first
- Keep the wstore directory writable and monitored for disk space
When it happens
Trigger: QueueLayoutActionForTab fails: tab not found (GetLayoutIdForTab), LayoutState missing, or DBUpdate write failure while persisting PendingBackendActions.
Common situations: Applying a layout to a tab deleted concurrently; DB write errors (disk full, permissions); calling with a tabId created outside normal CreateTab flow so LayoutState is unset.
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
- unable to get layout state for given id %s: %w
- unable to update layout state with new actions: %w
- unable to create block to apply portable layout to tab %s: %
- unable to find client: %w
- error getting window: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/7d664ec254ed250b.
Report an issue: GitHub.