Skip to content

Browser tool auto-attaches a screenshot to nearly every Code Mode result, permanently inflating history and app-server memory #40175

Open

Description

@TatsuKo-Tsukimi

What version of the Codex App are you using?

26.818.31338 (build 6892); codex-cli 0.149.0-alpha.4

What subscription do you have?

rate_limits payloads report plan_type: prolite

What platform is your computer?

macOS 26.4, Apple Silicon (arm64), 48 GB RAM

What issue are you seeing?

When the active model runs in code_mode_only mode (e.g. gpt-5.6-sol), every tool call is routed through the node_repl js tool. If the script touches the in-app browser at all, the tool result comes back with a full data:image/png;base64,... screenshot attached — even when the script never asked for one.

Measured over a single ~6.5 hour session:

node_repl :: js calls 864
calls whose result contained an image 347
of those, scripts referencing any screenshot/image API 3
images attached without being requested 344 (99.1%)

Example of a script that came back with an image attached — it only reads text:

const tab = await browser.tabs.new();
await tab.goto("http://127.0.0.1:<port>/");
await tab.playwright.waitForTimeout(1500);
nodeRepl.write(await tab.playwright.locator("body").innerText({ timeoutMs: 5000 }));

Downstream effects, all measured:

  1. Rollout size. That session's rollout reached 306 MB in 6.5 hours; 91% of its bytes were base64 image data (650 images).
  2. Compaction write amplification. Compaction itself works correctly — the retained-history snapshot rises and falls as expected. But each snapshot re-serializes the retained images. 64 snapshots wrote 188 MB to disk while live retained history peaked at 6.3 MB, i.e. roughly 30x write amplification.
  3. app-server memory. The app-server process reached 22.3 GB physical footprint after 3d20h uptime with 21 rollouts open, of which 21.2 GB was compressed/swapped, growing at roughly 5.5 GB/day. On a 48 GB machine this consumed essentially the entire compressor and filled swap.
  4. Disk. The local sessions directory grew from 140 GB to 182 GB in 4 days (378 new rollout files).

Two notes for whoever triages this:

  • RSS hides the memory growth. Resident was only ~1.0 GB because the rest was compressed; vmmap --summary <pid> | grep "Physical footprint" is the metric that shows it.
  • The heap was dominated by MALLOC_SMALL live allocations (20.3 GB across 5188 regions) rather than MALLOC_LARGE (1.8 GB), so the memory is mostly parsed history structures, not the image blobs themselves.

What steps can reproduce the bug?

  1. Use a model whose metadata is tool_mode: code_mode_only (e.g. gpt-5.6-sol), with the bundled browser plugin enabled.
  2. In Code Mode, run a script that only reads text from a page and never calls any screenshot or image API — for example the snippet above, against any local or public URL.
  3. Inspect the resulting mcp_tool_call_end entry in the session rollout .jsonl.
  4. Its output array contains a data:image/png;base64,... item the script never requested.
  5. Keep working in that session and watch rollout size and app-server footprint grow.

Session ID deliberately omitted — the conversations involved contain confidential work. Happy to supply one privately if it helps.

What is the expected behavior?

Any one of these would address it:

  • Attach a screenshot only when the script actually requests one.
  • Provide a switch to disable auto-attachment. I could not find one: I checked the bundled browser plugin's browser-service.mjs and every NODE_REPL_* / BROWSER_USE_* string in the node_repl binary, and there is no disableScreenshot-style option.
  • Elide or downscale image payloads when writing compaction snapshots, so a retained image is not re-serialized on every subsequent compaction.
  • Apply a low imageDetail default to auto-attached images.

Additional information

These mitigations have independent value: the first fixes the source, while the compaction change fixes the ~30x amplification on its own and would still help if auto-attachment turns out to be intentional.

There is also no retention policy for the sessions directory, so all of the above accumulates permanently.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    on Aug 23, 2026
  2. github-actions commented on Aug 23, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

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

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbrowserbugSomething isn't workingperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions