Bug Description
When an MCP tool (e.g., mcp_filesystem_read_media_file) returns a base64-encoded image with an incorrect MIME type declaration (declares image/png but the actual data is JPEG), the API returns a 400 error. More critically, this single error permanently corrupts the entire conversation — every subsequent message in that session fails with the same 400 error, regardless of content.
Steps to Reproduce
- Have a file with
.png extension that actually contains JPEG-encoded data (common when images are saved/exported with wrong extension)
- In a Copilot Chat conversation, trigger an MCP tool that reads this image (e.g.,
mcp_filesystem_read_media_file)
- The tool returns base64 data with
media_type: "image/png" but the actual bytes are JPEG
- First failure: API returns 400:
"The image was specified using the image/png media type, but the image appears to be a image/jpeg image"
- Permanent failure: Every subsequent message in this conversation — even a simple "hello" — returns the same 400 error
Error Message
Request Failed: 400
{"message":"messages.32.content.0.tool_result.content.0.image.source.base64: The image was specified using the image/png media type, but the image appears to be a image/jpeg image"}
Root Cause
The malformed tool result (with mismatched MIME type) becomes part of the conversation history. Since every new turn sends the full history to the API, and the API validates all images in the history, every subsequent request fails on the same poisoned entry.
Expected Behavior
- Graceful error handling: The conversation should not become permanently unusable due to a single bad tool result
- MIME type detection: When an MCP tool returns image data, the system should validate/detect the actual image format rather than trusting the declared MIME type (JPEG starts with
FF D8, PNG starts with 89 50 4E 47 — a 4-byte check is sufficient)
- Recovery mechanism: At minimum, the poisoned tool result should be stripped or corrected in subsequent turns so the conversation can continue
Workaround
- The affected conversation cannot be recovered — user must start a new conversation
- Convert the problematic image file to its correct format beforehand:
PIL.Image.open(path).save(path, format='PNG')
Environment
- VS Code: latest stable (April 2026)
- GitHub Copilot Chat extension: 0.43.0
- Model: Claude Opus 4.6 (likely affects all models with image validation)
- OS: Windows 11
- MCP tool involved:
mcp_filesystem_read_media_file (filesystem MCP server)
Impact
This is particularly disruptive because:
- Users lose all conversation context when forced to start a new session
- The failure mode is confusing — users don't understand why even "hello" fails
- JPEG files with
.png extension are surprisingly common (screenshots, web downloads, exports from various tools)
Similar Issue
A similar bug was reported and fixed in another AI coding tool: anomalyco/opencode#15264 — "invalid image payload from file attachment poisons subsequent turns"
Suggested Fix
Either at the client level (VS Code extension) or server level:
# Detect actual format from magic bytes before sending to API
MAGIC = {b'\xff\xd8': 'image/jpeg', b'\x89PNG': 'image/png', b'GIF8': 'image/gif', b'RIFF': 'image/webp'}
actual_type = next((v for k, v in MAGIC.items() if data.startswith(k)), declared_type)
Bug Description
When an MCP tool (e.g.,
mcp_filesystem_read_media_file) returns a base64-encoded image with an incorrect MIME type declaration (declaresimage/pngbut the actual data is JPEG), the API returns a 400 error. More critically, this single error permanently corrupts the entire conversation — every subsequent message in that session fails with the same 400 error, regardless of content.Steps to Reproduce
.pngextension that actually contains JPEG-encoded data (common when images are saved/exported with wrong extension)mcp_filesystem_read_media_file)media_type: "image/png"but the actual bytes are JPEG"The image was specified using the image/png media type, but the image appears to be a image/jpeg image"Error Message
Root Cause
The malformed tool result (with mismatched MIME type) becomes part of the conversation history. Since every new turn sends the full history to the API, and the API validates all images in the history, every subsequent request fails on the same poisoned entry.
Expected Behavior
FF D8, PNG starts with89 50 4E 47— a 4-byte check is sufficient)Workaround
PIL.Image.open(path).save(path, format='PNG')Environment
mcp_filesystem_read_media_file(filesystem MCP server)Impact
This is particularly disruptive because:
.pngextension are surprisingly common (screenshots, web downloads, exports from various tools)Similar Issue
A similar bug was reported and fixed in another AI coding tool: anomalyco/opencode#15264 — "invalid image payload from file attachment poisons subsequent turns"
Suggested Fix
Either at the client level (VS Code extension) or server level: