Skip to content

capture_screenshot returns a stale frame when the target tab is hidden #3

Description

@stanzhang

capture_screenshot calls Page.captureScreenshot without checking that the target is visible. Chromium suspends canvas compositing for a hidden tab, so the call returns the last frame that tab painted — a real PNG of the right chart showing the wrong data.

This is hard to catch by eye because the DOM keeps updating underneath: the header, the quote and the status-bar clock in the returned image are current, while the candles, the price axis and any Pine tables are frozen at whatever was on screen when the tab was last foregrounded.

Reproduce

  1. Two chart tabs open, A in front, B behind.
  2. Attach to B (tab_switch, or point ~/.tv-mcp/active-target.json at it).
  3. chart_set_symbol on B to something clearly different from what B showed before.
  4. capture_screenshot.

The PNG shows B's previous symbol/date. chart_get_state correctly reports the new one, so the tool result and the image disagree and only the image is wrong.

Observed on 2.3.0 / Desktop 3.3.0 / macOS, with a chart in a background tab of a second Desktop window: three consecutive captures 40s apart were byte-similar frozen charts whose only changing element was the clock.

Why it matters

An agent building a report treats the PNG as evidence. A stale frame of the correct instrument is the worst failure shape available here — it is plausible, it is silent, and it survives review.

Suggested fix

src/core/capture.js already has everything it needs nearby: src/core/tab.js implements _isTargetVisible() via document.visibilityState. Asserting that before the CDP capture, and failing with a clear category (or at minimum returning visible: false in the result so callers can refuse), would close it.

const vis = await evaluate('document.visibilityState');
if (vis !== 'visible') throw new ClassifiedError(CATEGORIES.CHART_LOADING,
  'Target tab is hidden; a capture would return a stale frame', { hint: 'Front the tab with tab_switch first.' });

Happy to send a PR if the shape looks right.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions