Skip to content

image-shrink recovery re-encodes oversized images on every API call — repaired images never persisted to session history #61994

Description

@tsjc

Summary

If an image in session history exceeds a provider limit (e.g. Anthropic's 8000px max dimension), every API call fails at the provider, triggers image-shrink recovery, retries successfully — but the shrunken images are never written back to session history, so the identical failure repeats on every subsequent call for the life of the session.

Environment

  • hermes-agent 0.18.0 (v2026.7.1-368-g5b04a024a), macOS 26.5.1 (Apple Silicon)
  • Model: anthropic/claude-opus-4.8 via OpenRouter; Telegram DM session

Steps to reproduce

  1. Send a screenshot taller than 8000px into a chat session (ours: tall full-page screenshots, 3.4–5.0MB source files).
  2. Continue the conversation past the point where the image is in retained history.
  3. Observe every subsequent API call.

Actual behavior (from agent.log)

Each call: streams for 20–57s → provider rejects with

messages.N.content.5.image.source.base64.data: At least one of the image dimensions exceed max allowed size: 8000 pixels

image-shrink recovery: re-encoded 4 image part(s) (~1.2–2.4s, re-reads the multi-MB source files) → retry succeeds → repaired images are discarded → next call fails identically.

We logged 101 recurrences over ~24h in one session. In a sampled 84.8s turn, the failed first attempt + re-encode accounted for 52.5s (62%) of total wall-clock. Cumulative waste: roughly 50–85 minutes of pure provider round-trip time, plus doubled per-call token/latency cost — the user experience is that the agent is mysteriously 2× slower forever after posting one tall screenshot.

Suggested fix

Either (a) persist the post-shrink image parts back into session history after a successful recovery retry, or (b) validate/downscale images against provider dimension limits at ingestion time so oversized originals never enter history. (a) also fixes existing poisoned sessions on their next turn.

Workaround

Start a fresh session (/new); the poisoned history stays behind.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/sessionsSession lifecycle, resume, persistence, historycomp/agentCore agent runtime: loop, agent_init, prompt builder, context-compression, responses endpointprovider/anthropicAnthropic native Messages APIsweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions