wavetermdev/waveterm · error
Layout model not found
Error message
Layout model not found
What it means
captureBlockScreenshot needs the current static tab's LayoutModel to locate a block's DOM node and compute its on-screen rectangle for Electron's capturePage. getLayoutModelForStaticTab() returned null, meaning no layout model is registered for the active static tab. This is a lifecycle/state error: the screenshot RPC was invoked when the tab's layout system was not initialized or has been torn down.
Source
Thrown at frontend/app/store/tabrpcclient.ts:25
import { WorkspaceLayoutModel } from "@/app/workspace/workspace-layout-model";
import { getLayoutModelForStaticTab } from "@/layout/index";
import { base64ToArrayBuffer } from "@/util/util";
import { RpcResponseHelper, WshClient } from "./wshclient";
import { RpcApi } from "./wshclientapi";
export class TabClient extends WshClient {
constructor(routeId: string) {
super(routeId);
}
handle_captureblockscreenshot(rh: RpcResponseHelper, data: CommandCaptureBlockScreenshotData): Promise<string> {
return this.captureBlockScreenshot(data.blockid);
}
async captureBlockScreenshot(blockId: string): Promise<string> {
const layoutModel = getLayoutModelForStaticTab();
if (!layoutModel) {
throw new Error("Layout model not found");
}
const node = layoutModel.getNodeByBlockId(blockId);
if (!node) {
throw new Error(`Block not found: ${blockId}`);
}
const displayContainer = layoutModel.displayContainerRef.current;
if (!displayContainer) {
throw new Error("Display container not found");
}
const containerRect = displayContainer.getBoundingClientRect();
const additionalProps = layoutModel.getNodeAdditionalProperties(node);
let electronRect: Electron.Rectangle;
if (!additionalProps?.rect) {View on GitHub (pinned to a4447c1563)
Solutions
- Check that the block's tab is open and its layout has fully mounted before calling the RPC
- Retry after a short delay (e.g. wait for the tab to render) if called during tab transitions
- Confirm the call is routed to the correct tab's TabRpcClient, not a stale/closed one
- If screenshotting many blocks, fetch the layout model once after confirming it exists rather than during transitions
Example fix
// before
const layoutModel = getLayoutModelForStaticTab();
if (!layoutModel) {
throw new Error("Layout model not found");
}
// after
const layoutModel = getLayoutModelForStaticTab();
if (!layoutModel) {
await waitForLayoutModel(500);
layoutModel = getLayoutModelForStaticTab();
}
if (!layoutModel) {
throw new Error("Layout model not found");
} Defensive patterns
Strategy: retry
Validate before calling
const layoutModel = getLayoutModelForStaticTab();
if (layoutModel == null) {
throw new Error("cannot capture screenshot: tab layout not mounted yet");
} Type guard
function hasLayoutModel(): boolean {
return getLayoutModelForStaticTab() != null;
} Try / catch
try {
const pngData = await rpcService.call("captureblockscreenshot", { blockid });
} catch (e) {
if (String(e).includes("Layout model not found")) {
await delay(150);
pngData = await rpcService.call("captureblockscreenshot", { blockid });
} else {
throw e;
}
} Prevention
- Gate screenshot APIs behind tab-mounted state
- Cancel pending screenshot RPCs when tabs/windows close
- Avoid layout-dependent RPCs during tab transitions
- Add a readiness flag/event emitted once the layout model registers
When it happens
Trigger: handle_captureblockscreenshot RPC arrives before the tab's React layout has mounted, after the tab/window was closed, or in a context (e.g. a preview/test static tab) where getLayoutModelForStaticTab() has no registered model.
Common situations: Client calls captureblockscreenshot right after tab switch/creation before mount completes; screenshotting a block in a closed window; running in an environment (storybook/tests/web) where the static-tab layout model is never set.
Related errors
- Block not found: ${blockId}
- Display container not found
- Block not found in tab: ${blockId}
- rpc command "${msg.command}" not supported by [${this.routeI
- Invalid node
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/d9c15791c2b60884.
Report an issue: GitHub.