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

  1. 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
  2. Re-fetch the tab and confirm Tab.LayoutState is non-empty before applying
  3. Retry the ApplyPortableLayout call; note already-created blocks may remain and a re-run clears the tree first
  4. 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

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


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