Skip to content

Validate images before they enter conversation context - #33

Merged
pufit merged 1 commit into
mainfrom
pufit/image-validation
Apr 7, 2026
Merged

Validate images before they enter conversation context#33
pufit merged 1 commit into
mainfrom
pufit/image-validation

Conversation

@pufit

@pufitpufit commented Apr 7, 2026

Copy link
Copy Markdown
Member

Summary

  • PreToolUse hook on Read validates image files (magic bytes + size) before the CLI can base64-encode them into conversation context — prevents the "Could not process image" poison loop where one bad image makes every subsequent turn fail
  • Telegram pipeline validation checks base64 image data before constructing content blocks, replacing invalid images with descriptive text
  • Error handler railguard detects poisoned context errors and resets the CLI session as a last resort for images entering via MCP tools or sub-agents
  • Fix pre-existing test failure in test_non_interactive_proxy_mode — host ANTHROPIC_API_KEY leaked through patch.dict(clear=False)

Context

On April 3, session 665441de got stuck in an infinite error loop after attempting to read images from a private GitHub issue. The CLI's Read tool base64-encoded what was likely an HTML auth redirect page (saved with a .png extension), and the API rejected it. Since the CLI re-sends full conversation history on every turn, the bad image block poisoned the entire session.

Test plan

  • 326 tests pass (0 failures, up from 325/1)
  • Inline validation tests: 13/13 cases covering valid PNG/JPEG/GIF/WebP, HTML-as-image, empty files, oversized files, RIFF-not-WebP, non-image files, and base64 data validation

Generated by Nerve

The CLI's Read tool detects images by file extension and base64-encodes
them into content blocks. If a file has an image extension but contains
non-image data (e.g. an HTML redirect from an auth-gated URL), the API
rejects it with 400 "Could not process image". The bad block persists
in conversation history, causing every subsequent turn to fail.
Layer 1 — PreToolUse hook on Read:
- Check magic bytes (PNG/JPEG/GIF/WebP signatures) and file size (<5MB)
- Deny Read with clear error message if invalid — conversation intact
- Detects HTML pages saved with image extensions
Layer 1b — Nerve-sourced image validation (Telegram pipeline):
- Validate base64 data before constructing content blocks
- Replace invalid images with descriptive text block
Layer 2 — Error handler railguard:
- Detect "Could not process image/document" in generic exception handler
- Clear sdk_session_id so next turn starts fresh CLI (no --resume)
- Last resort for images entering via MCP tools or CLI internals
Also fix pre-existing test_proxy failure: test_non_interactive_proxy_mode
leaked host ANTHROPIC_API_KEY through patch.dict(clear=False).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@pufit