[BUG] Image-drop ingestion forces a /compact whose recap drops the in-flight task and fabricates a current task from older context

Resolved 💬 6 comments Opened Apr 27, 2026 by batchprocess128 Closed Jun 2, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When a user drops an image into Claude Code that exceeds the inline dimension limit, Claude Code prompts a /compact. Running it preserves the image, but the auto-generated recap drops the user's most recent message (the one that triggered the compaction) and fabricates a "current task" from older context fragments instead. The user gets no in-tool indication that this happened.

What Should Happen?

The recap should reflect the message that triggered the compaction, including the full intent of the user's most recent turn, however that turn is summarized.

Error Messages/Logs

※ recap: Goal: [BUSINESS NAME REDACTED] and filing [INDIVIDUAL NAMES REDACTED]
complaints while running [PERSONAL CASE TYPE REDACTED]. Current task: ping Hermes
in his tab to pick up the Polymarket research dispatch waiting at
Desktop/agent-state/.

Steps to Reproduce

  1. Have an active conversation with substantive recent context.
  2. Drop an image >2000px inline into the terminal.
  3. Claude Code prompts: "An image in the conversation exceeds the dimension limit for many-image requests (2000px). Run /compact to remove old images from context, or start a new session."
  4. Run /compact.
  5. After compaction, the ※ recap: reports a "current task" that does not match the message which triggered the compaction. The triggering message is absent from the recap entirely.
  6. Claude proceeds based on the fabricated recap, asking about the wrong thing or attempting to redo work that is already complete.

Claude Model

Opus (specifically claude-opus-4-7[1m], Opus 4.7 with 1M context)

Claude Code Version

2.1.119 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS, version 2.14)

Is this a regression?

I don't know.

Additional Information

Note on redaction

The recap shown in "Error Messages/Logs" has personal-context names redacted as [REDACTED] for privacy. Redaction does not affect the technical claim. The bug is that the recap describes a fabricated current task regardless of what the names are.

Concrete repro context (2026-04-27 session)

A voice-insight image was dropped into the terminal as part of a message proposing a tagline tweak. The image exceeded 2000px. Compaction was prompted. The recap that appeared is shown in "Error Messages/Logs" above.

Verifiable timeline. All times 2026-04-27. UTC canonical (Z suffix); PT shown alongside.

| Time (UTC) | Time (PT) | Event |
|---|---|---|
| 15:28Z | 08:28 | Polymarket task dispatched to a peer agent (Hermes) by writing the dispatch file. |
| 15:30Z | 08:30 | Dispatch logged in AGENT_LOG.md. |
| 15:35Z | 08:35 | Peer agent posts ACK file. |
| 15:41Z | 08:41 | Peer agent saves the completed report (~17 KB). |
| 15:42Z | 08:42 | Peer agent logs task completion. |
| 15:44Z | 08:44 | User takes a screenshot anticipating compaction will lose context. |
| 15:59Z | 08:59 | User saves the post-compact terminal text to file. The recap line above is visible at this point. |

The recap is wrong on three layers. (1) The state described never existed: the peer agent had completed the task at 08:42, before the recap was generated. (2) Even if the state were correct, a background-async task is not the in-flight conversational task. (3) The user's actual current message (voice-insight image + tagline-tweak proposal) is missing from the recap entirely.

The recap is constructing a "current task" from older context fragments while the message that triggered the compaction is absent. Pre-compact terminal state was preserved manually by the user; without that defensive triage there would be no recovery path.

Architectural fix proposal

Treat artifact drops as auto-save-and-link rather than inline-embed. When a user drags or drops a file or image into the terminal:

  • Auto-save the artifact to a known location (session-scoped temp dir, or ~/Desktop with a timestamp).
  • Insert only the file path into the message body.
  • Let Claude read the artifact lazily via the existing Read tool when relevant.

Edge cases:

  • Clipboard paste: same flow as drag-drop.
  • Multi-image input: each artifact saved separately, paths inserted in order.
  • Inline-when-small: artifacts safely under the dimension limit can still inline; rule is scoped to oversize ingestion only.

The change is in the ingestion layer. The model-facing capability (path-based Read tool) has already shipped.

Reference implementation in an adjacent harness

Hermes Agent (hermes-agent, an open-source CLI agent harness running in the same multi-agent stack as the affected Claude Code session) handles this exact pattern in production today. In cli.py:

  • _detect_file_drop() intercepts dragged/pasted paths before the input is interpreted as inline message content. Returns a structured dict {path, is_image, remainder}. The drop becomes a path-reference, never an inline embedding.
  • _format_image_attachment_badges() renders [📎 Image #N] badges in the user's terminal so the attachment is visible as a reference, not as raw bytes.
  • _should_auto_attach_clipboard_image_on_paste() extends the same path-link semantics to clipboard pastes.
  • _IMAGE_EXTENSIONS defines the suffix set that triggers the drop-path code path.

The model reads the artifact lazily via its path-based read primitive. There is no oversize-input cascade because the input was never inline. There is no forced compaction because compaction was never required. There is no recap layer to fabricate because there is no compaction-induced recap.

Each of the edge cases above (clipboard paste, multi-image, inline-when-small) is handled by this implementation, so the proposal is de-risked by working code in the same ecosystem.

Patch-level fallback

If the architectural change is too large for one issue, the recap layer alone can be made safer: the post-compact recap should preserve the most recent user message verbatim (or as a load-bearing summary) and should not substitute a different earlier task; the compaction should warn before running that recent context may be lost; the recap should explicitly acknowledge what was preserved and what was elided so the user can flag a fabrication in the moment. The architectural fix is preferable because it removes the root cause; the patch addresses the symptom.

Workaround for users today

No tool changes required:

  • Save files to a known location on disk.
  • Reference the path in the message body: "look at the image at ~/Desktop/<filename>".
  • Claude reads via the Read tool. No compaction triggered.

This works today. But it shouldn't be required.

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗