wavetermdev/waveterm · error
unable to update layout state with new actions: %w
Error message
unable to update layout state with new actions: %w
What it means
After appending the new LayoutActionData to PendingBackendActions, QueueLayoutAction persists the modified LayoutState via wstore.DBUpdate. This error wraps any failure of that update (write error, DB closed, serialization problem). The in-memory change is not committed.
Source
Thrown at pkg/wcore/layout.go:102
if err != nil {
return fmt.Errorf("unable to get layout state for given id %s: %w", layoutStateId, err)
}
for i := range actions {
if actions[i].ActionId == "" {
actions[i].ActionId = uuid.New().String()
}
}
if layoutStateObj.PendingBackendActions == nil {
layoutStateObj.PendingBackendActions = &actions
} else {
*layoutStateObj.PendingBackendActions = append(*layoutStateObj.PendingBackendActions, actions...)
}
err = wstore.DBUpdate(ctx, layoutStateObj)
if err != nil {
return fmt.Errorf("unable to update layout state with new actions: %w", err)
}
return nil
}
func QueueLayoutActionForTab(ctx context.Context, tabId string, actions ...waveobj.LayoutActionData) error {
layoutStateId, err := GetLayoutIdForTab(ctx, tabId)
if err != nil {
return err
}
return QueueLayoutAction(ctx, layoutStateId, actions...)
}
func ApplyPortableLayout(ctx context.Context, tabId string, layout PortableLayout, recordTelemetry bool) error {
actions := make([]waveobj.LayoutActionData, len(layout)+1)
actions[0] = waveobj.LayoutActionData{ActionType: LayoutActionDataType_ClearTree}
for i := 0; i < len(layout); i++ {
layoutAction := layout[i]View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the wrapped %w error to identify the wstore.DBUpdate failure cause
- Ensure the passed ctx is live (not cancelled/timed out) when queueing actions
- Check disk space and write permissions on the wave store data directory
- Retry QueueLayoutActionForTab; actions are idempotent-keyed by ActionId so a requeue is safe
Example fix
// before ctx := context.Background() // never cancelled, but may outlive app // after ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := wcore.QueueLayoutActionForTab(ctx, tabId, action)
Defensive patterns
Strategy: try-catch
Validate before calling
select {
case <-ctx.Done():
return ctx.Err()
default:
}
// proceed with QueueLayoutAction using a live context Try / catch
if err := wcore.QueueLayoutActionForTab(ctx, tabId, actions...); err != nil {
if strings.Contains(err.Error(), "unable to update layout state") {
// retry with backoff; check disk space / permissions
}
} Prevention
- Pass a live (non-cancelled) context with a sane timeout
- Monitor disk space on the wave store volume
- Requeue safely on failure — ActionIds are auto-generated per attempt
When it happens
Trigger: wstore.DBUpdate fails while saving a LayoutState after appending actions — disk full, DB IO error, context cancellation/timeout on ctx, or object validation failure during update.
Common situations: Disk full or read-only filesystem on the machine hosting the wave store; parent context already cancelled or timed out when QueueLayoutAction is called; transient DB errors during startup/shutdown.
Related errors
- unable to get layout state for given id %s: %w
- unable to queue layout actions for portable layout: %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/587a77b71d76f73b.
Report an issue: GitHub.