wavetermdev/waveterm · error

failed to capture screenshot: %w

Error message

failed to capture screenshot: %w

What it means

This error wraps any failure from the wshclient.CaptureBlockScreenshotCommand RPC, which asks the Wave tab's route to render a block (widget) and return screenshot data. It is thrown by the AI capture_screenshot tool when the underlying RPC returns an error — e.g. the tab route is unavailable, the block cannot be resolved/rendered, or the RPC times out (5s context deadline). The original cause is preserved via %w so unwrap it for details.

Source

Thrown at pkg/aiusechat/tools_screenshot.go:45

			return "", fmt.Errorf("missing or invalid widget_id parameter")
		}

		ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancelFn()

		fullBlockId, err := wcore.ResolveBlockIdFromPrefix(ctx, tabId, blockIdPrefix)
		if err != nil {
			return "", err
		}

		rpcClient := wshclient.GetBareRpcClient()
		screenshotData, err := wshclient.CaptureBlockScreenshotCommand(
			rpcClient,
			wshrpc.CommandCaptureBlockScreenshotData{BlockId: fullBlockId},
			&wshrpc.RpcOpts{Route: wshutil.MakeTabRouteId(tabId)},
		)
		if err != nil {
			return "", fmt.Errorf("failed to capture screenshot: %w", err)
		}

		return screenshotData, nil
	}
}

func GetCaptureScreenshotToolDefinition(tabId string) uctypes.ToolDefinition {
	return uctypes.ToolDefinition{
		Name:        "capture_screenshot",
		DisplayName: "Capture Screenshot",
		Description: "Capture a screenshot of a widget and return it as an image",
		ToolLogName: "gen:screenshot",
		Strict:      true,
		InputSchema: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"widget_id": map[string]any{
					"type":        "string",

View on GitHub (pinned to a4447c1563)

Solutions

  1. Unwrap the error (%v with errors.Unwrap or errors.As) to see the root cause (timeout vs not-found vs route error)
  2. Verify the widget_id/blockId is valid and the block still exists in the given tab
  3. Confirm the tab is open and its wsh route is connected before calling the RPC
  4. Retry once if the failure was a deadline/timeout, or increase the 5s context timeout
  5. Check that the block type actually supports screenshot capture

Example fix

// before
screenshotData, err := wshclient.CaptureBlockScreenshotCommand(rpcClient, wshrpc.CommandCaptureBlockScreenshotData{BlockId: fullBlockId}, &wshrpc.RpcOpts{Route: wshutil.MakeTabRouteId(tabId)})
if err != nil { return "", fmt.Errorf("failed to capture screenshot: %w", err) }
// after
screenshotData, err := wshclient.CaptureBlockScreenshotCommand(rpcClient, wshrpc.CommandCaptureBlockScreenshotData{BlockId: fullBlockId}, &wshrpc.RpcOpts{Route: wshutil.MakeTabRouteId(tabId), TimeoutMs: 10000})
if err != nil { return "", fmt.Errorf("failed to capture screenshot for block %s: %w", fullBlockId, err) }
Defensive patterns

Strategy: try-catch

Validate before calling

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := wcore.ResolveBlockIdFromPrefix(ctx, tabId, widgetId); err != nil {
    return fmt.Errorf("invalid widget %s in tab %s: %w", widgetId, tabId, err)
}

Type guard

func isTimeoutErr(err error) bool {
    var ne net.Error
    return errors.As(err, &ne) && ne.Timeout()
}

Try / catch

screenshot, err := captureTool(input)
if err != nil {
    if isTimeoutErr(err) {
        // retry once with longer deadline
    }
    log.Printf("screenshot capture failed: %v", err)
    return fmt.Errorf("capture_screenshot unavailable: %w", err)
}

Prevention

When it happens

Trigger: Calling the capture_screenshot AI tool where CaptureBlockScreenshotCommand over RpcOpts{Route: MakeTabRouteId(tabId)} fails: tab route not connected, invalid/removed block id, renderer failure, or the 5-second context timeout elapsing before a response.

Common situations: AI agent passes a stale widget_id for a block that was closed; the target tab was closed or the wsh route is down; the block contents hang (e.g. a stuck terminal) causing the 5s deadline to expire; running outside the Wave app where no bare RPC client connection exists.

Related errors


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