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

  1. Inspect the wrapped %w error to identify the wstore.DBUpdate failure cause
  2. Ensure the passed ctx is live (not cancelled/timed out) when queueing actions
  3. Check disk space and write permissions on the wave store data directory
  4. 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

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


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