wavetermdev/waveterm · error
Display container not found
Error message
Display container not found
What it means
captureBlockScreenshot found the layout node for the block, but the LayoutModel's displayContainerRef.current is null — the DOM element that hosts all blocks is not mounted. The container's bounding rect is required to compute absolute coordinates for Electron's capturePage, so the operation cannot proceed.
Solutions
- Wait until the tab is fully rendered before capturing (e.g. await a mounted flag or requestAnimationFrame)
- Retry the RPC after a short delay if it races mount/unmount
- Cancel queued screenshot requests when the tab/window closes
- Verify the block is in the visible tab, not a background tab whose container is unmounted
Example fix
// before
const containerRect = displayContainer.getBoundingClientRect();
// after
if (!displayContainer) {
await new Promise((r) => requestAnimationFrame(r));
displayContainer = layoutModel.displayContainerRef.current;
if (!displayContainer) throw new Error("Display container not found");
}
const containerRect = displayContainer.getBoundingClientRect(); Defensive patterns
Strategy: retry
Validate before calling
const displayContainer = getLayoutModelForStaticTab()?.displayContainerRef.current;
if (!displayContainer) {
throw new Error("display container not mounted; cannot capture");
} Type guard
function displayContainerMounted(): boolean {
return getLayoutModelForStaticTab()?.displayContainerRef.current != null;
} Try / catch
try {
const pngData = await rpcService.call("captureblockscreenshot", { blockid });
} catch (e) {
if (String(e).includes("Display container not found")) {
await nextFrame();
pngData = await rpcService.call("captureblockscreenshot", { blockid });
} else {
throw e;
}
} Prevention
- Defer captures until after mount (requestAnimationFrame or mounted callback)
- Skip captures for background tabs whose containers are unmounted
- Guard ref consumers against null .current before layout commit
When it happens
Trigger: The RPC runs while the tab's display container is unmounted — during tab close, window minimize with unmounted DOM, or before the layout component's ref has attached (very early after mount).
Common situations: Automated screenshot right after window/tab creation racing React's commit; capturing during workspace/tab teardown; tests or headless environments where the display container never renders.
Related errors
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/470508cc381fac23.
Report an issue: GitHub.
Appendix: source
Thrown at frontend/app/store/tabrpcclient.ts:35
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) {
// Bug: rect is not set when there is only one block in the layout
// In this case, use the full container rect
electronRect = {
x: Math.round(containerRect.x),
y: Math.round(containerRect.y),
width: Math.round(containerRect.width),
height: Math.round(containerRect.height),
};
} else {
const blockRect = additionalProps.rect;View on GitHub (pinned to a4447c1563)