Skip to content

Clipboard moodboards over 5 MB are dropped before the trajectory with a generic read error #349

Description

@yxlyx

Summary

On macOS, pasting a high-resolution moodboard with Ctrl-V can print:

· couldn't read the clipboard image

The prompt can then be submitted without the image. The resulting trajectory is text-only even though the user's wording assumes the moodboards are visible, so the agent proceeds with materially wrong visual context.

This happened in a real design trajectory: the user entered hm the images are ugly.. can u try using these moodboards, pasted moodboards, received the message above, and the agent continued without them.

Environment / trajectory evidence

  • Codegraff: 0.0.231
  • Platform: macOS
  • Provider/model: Codex gpt-5.6-sol (vision-capable)
  • Run: fe6a9d36547b27dd
  • Session: 535a514303c7c463e02bbaaaabd615ff
  • Trace: .graff/traces/fe6a9d36547b27dd.jsonl
  • Behavior log identifies the relevant follow-up as trajectory node 5 / turn 3.
  • Turn 3's API requests were at most 842,217 bytes. That is consistent with the failed image never being staged; a base64 payload from a >5 MB clipboard PNG would alone exceed ~6.7 MB.
  • The API/tool trace records no clipboard staging/rejection event, so the visual-context loss is not diagnosable from the trajectory alone.

Root cause in current main

The exact UI string uniquely identifies this path:

  1. src/readline.zig calls grabClipboardImage, gets an image path, then prints couldn't read the clipboard image when stageImagePath returns .read_fail.
  2. stageImagePath reads with a hard .limited(5 * 1024 * 1024) limit and collapses oversize, missing-file, read, and allocation failures into the same read_fail result.
  3. grabClipboardImage always exports the pasteboard as PNG. Large screenshots/moodboards can easily exceed 5 MB even when their dimensions are reasonable for model vision.
  4. The grabber uses the shared fixed path /tmp/.harness-clip.png, which also makes concurrent sessions race-prone and leaves no per-paste diagnostics or cleanup ownership.

The most likely trigger in this case is the exported PNG exceeding 5 MB. The current result type makes that impossible to distinguish from other read failures.

Expected behavior

Clipboard moodboards should either be normalized and attached successfully, or fail with an actionable reason before the user unknowingly submits a text-only prompt.

Suggested acceptance criteria

  • Clipboard images larger than 5 MB are resized/re-encoded to a bounded provider-safe payload when dimensions permit.
  • If attachment still cannot proceed, report the actual reason and size, e.g. clipboard image is 8.3 MB; maximum is 5 MB, rather than couldn't read.
  • Use distinct stage errors such as not_found, too_large, read_error, and allocation_error instead of one read_fail bucket.
  • Use a unique temporary path per process/paste and clean it up after staging.
  • Record an attachment accepted/rejected trace event with reason, source, MIME type, dimensions, and byte count (never the image payload), so trajectory inspection explains missing visual context.
  • Add regression coverage for an exported PNG over 5 MB and for two concurrent sessions pasting images.
  • Consider preventing or strongly warning on prompt submission when the text contains a failed image-dependent request immediately after an attachment rejection.

Related issues

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