Repository navigation
Python: Percent-encoded base64 data URIs fail media type detection #9653
Description
Observed Behavior
detect_media_type_from_base64(data_uri=...) rejects a valid base64 data URL when its payload contains URL-escaped characters. Encoding / as %2F changes an otherwise working PNG input into ValueError: Invalid base64 data provided.
Content.from_uri accepts both representations and identifies the same media type, but the internal byte-extraction helper also fails on the escaped representation. No provider request is needed to observe this.
Expected Behavior
Equivalent literal and URL-escaped base64 payloads should yield the same media detection result and decoded bytes. The Fetch data-URL processing algorithm percent-decodes the body before base64 decoding. Python's built-in data handler reads identical bytes for both inputs below.
Steps to Reproduce
Compare the literal and percent-encoded forms of the same small PNG data URL using the public media-detection helper. The literal form returns image/png; the equivalent escaped form raises an exception.
Minimal Reproduction
from urllib.parse import quote
from urllib.request import urlopen
from agent_framework import detect_media_type_from_base64
payload = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
literal = "data:image/png;base64," + payload
escaped = "data:image/png;base64," + quote(payload, safe="")
# These are local data URLs; this does not contact a server.
with urlopen(literal) as first, urlopen(escaped) as second:
assert first.read() == second.read()
print(detect_media_type_from_base64(data_uri=literal)) # image/png
print(detect_media_type_from_base64(data_uri=escaped)) # raises ValueErrorError Messages and Stack Traces
ValueError: Invalid base64 data provided.
Package Versions
Source snapshot at 678c6616aa4c73ecfc28cc6fc119a3928ba04024; _types.py blob 629593b8839f6828887af9668462ef7ba2fea837. The run loaded the seven complete, unchanged source modules required by the official agent_framework initializer and these public exports. It reused an existing environment with typing-extensions 4.16.0. This was not a fresh installation or a complete SDK test; the environment's installed agent-framework-core 1.19.0 metadata does not identify the source snapshot.
Python Version
CPython 3.14.3, x64
Operating System
Windows
Regression
Unknown
Additional Context
The 69-byte PNG is a complete 1x1 image with computed chunk CRCs. Its literal data URL is the normal control; its URL-escaped form contains identical bytes. Content.from_data also preserves those bytes. The initial module-level observation and the later public-export verification use this same PNG, not additional independent cases.
The current _parse_data_uri leaves the payload URL-escaped, and both detection and byte extraction pass it to the base64 decoder. This is separate from #8905/#8918, which addressed URI parameters, media-type defaults and validation. No production patch has been started. Would decoding the payload's URL escapes before base64 processing be the appropriate direction?
No provider/cloud calls, image rendering, complete SDK suite, other Python versions or other operating systems were tested.
AI assistance: Reproduction analysis and this issue description.
Acknowledgements
- I searched existing issues and did not find a duplicate.
- I personally verified this behavior and the reproduction details are authentic.
- I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
MuonChaser commentedon Oct 23, 2026
I’ll take this on as a bounded data-URI compatibility fix: percent-decode the payload once before base64 processing, preserving literal
+, raw-input behavior, and existing metadata/error handling. I’ll add offline regressions for media detection and Content byte extraction, including escaped/,+,=, and double-encoding.ktz03 commentedon Oct 23, 2026
I'd like to implement this fix once the maintainers confirm the direction; the report and normal-control reproduction are ready. Zhang Bowen (@MuonChaser), have you already started a patch? Please let me know so we can agree on who implements it and avoid duplicate work.