{"record":{"id":"76931e694c5eb93b","repo":"wavetermdev/waveterm","slug":"block-not-found-blockid","errorCode":null,"errorMessage":"Block not found: ${blockId}","messagePattern":"Block not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/app/store/tabrpcclient.ts","lineNumber":30,"sourceCode":"\nexport class TabClient extends WshClient {\n    constructor(routeId: string) {\n        super(routeId);\n    }\n\n    handle_captureblockscreenshot(rh: RpcResponseHelper, data: CommandCaptureBlockScreenshotData): Promise<string> {\n        return this.captureBlockScreenshot(data.blockid);\n    }\n\n    async captureBlockScreenshot(blockId: string): Promise<string> {\n        const layoutModel = getLayoutModelForStaticTab();\n        if (!layoutModel) {\n            throw new Error(\"Layout model not found\");\n        }\n\n        const node = layoutModel.getNodeByBlockId(blockId);\n        if (!node) {\n            throw new Error(`Block not found: ${blockId}`);\n        }\n\n        const displayContainer = layoutModel.displayContainerRef.current;\n        if (!displayContainer) {\n            throw new Error(\"Display container not found\");\n        }\n\n        const containerRect = displayContainer.getBoundingClientRect();\n        const additionalProps = layoutModel.getNodeAdditionalProperties(node);\n\n        let electronRect: Electron.Rectangle;\n\n        if (!additionalProps?.rect) {\n            // Bug: rect is not set when there is only one block in the layout\n            // In this case, use the full container rect\n            electronRect = {\n                x: Math.round(containerRect.x),\n                y: Math.round(containerRect.y),","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/app/store/tabrpcclient.ts#L12-L48","documentation":"captureBlockScreenshot resolved the tab's LayoutModel, but layoutModel.getNodeByBlockId(blockId) returned null — the given blockId does not exist in this tab's layout tree. The screenshot can only be taken from blocks actually rendered in the current tab, so an unknown blockId is rejected.","triggerScenarios":"handle_captureblockscreenshot called with a blockId that was closed, belongs to a different tab/window, was never created, or whose id string is malformed.","commonSituations":"Client caches blockIds and screenshots a block the user already closed; a UUID from another tab (blockIds are per-tab layout in this call path); typos or stale ids persisted in app state across reloads.","solutions":["Verify the blockId still exists (via the tab's block list / getfocusedblockdata) before calling","Ensure the RPC is sent on the TabRpcClient of the tab that owns the block","Listen for block-close/delete events and purge cached blockIds","Log the tabId+blockId pair to confirm they match the tab receiving the RPC"],"exampleFix":"// before\nawait rpcService.call(\"captureblockscreenshot\", { blockid: cachedBlockId });\n// after\nif (globalStore.get(tabLayoutModel.nodeMap).some((n) => n.data?.blockId === cachedBlockId)) {\n    await rpcService.call(\"captureblockscreenshot\", { blockid: cachedBlockId });\n} else {\n    cachedBlockId = null;\n}","handlingStrategy":"validation","validationCode":"const node = layoutModel?.getNodeByBlockId(blockId);\nif (!node) {\n    console.warn(\"skipping capture, block not in this tab:\", blockId);\n    return null;\n}","typeGuard":"function blockExistsInTab(blockId: string): boolean {\n    return getLayoutModelForStaticTab()?.getNodeByBlockId(blockId) != null;\n}","tryCatchPattern":"try {\n    const pngData = await rpcService.call(\"captureblockscreenshot\", { blockid });\n} catch (e) {\n    if (String(e).startsWith(\"Block not found:\")) {\n        purgeCachedBlockId(blockid);\n        return null;\n    }\n    throw e;\n}","preventionTips":["Subscribe to block close/delete events and drop cached ids","Route block-specific RPCs through the owning tab's TabRpcClient","Never persist blockIds across workspace restores without revalidation"],"tags":["frontend","screenshot","invalid-argument"],"backgroundTag":"block-id-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}