-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
- Package Name: azure-ai-agents
- Package Version: 1.1.0
- Operating System: macOS (ARM64)
- Python Version: 3.12.4
Describe the bug
The async AgentsClient (azure.ai.agents.aio.AgentsClient) fails on files.upload_and_poll() with a DecodeError, while the sync AgentsClient (azure.ai.agents.AgentsClient) succeeds for the exact same operation, endpoint, credentials, and file.
The async pipeline's ContentDecodePolicy.on_response attempts to JSON-deserialize the HTTP response body but receives raw binary/compressed data instead, causing json.JSONDecodeError: Expecting value: line 1 column 1 (char 0).
This appears to be a difference in how the async HTTP transport (aiohttp) handles response decompression compared to the sync transport (requests). The sync transport correctly decompresses the response before JSON parsing, while the async transport does not.
To Reproduce
- Install
azure-ai-agents==1.1.0andazure-identity - Run the following sync script — it succeeds:
from azure.ai.agents import AgentsClient
from azure.ai.agents.models import FilePurpose
from azure.identity import DefaultAzureCredential
client = AgentsClient(
endpoint="https://<endpoint>.services.ai.azure.com/api/projects/<project>",
credential=DefaultAzureCredential()
)
# ✅ This succeeds
uploaded_file = client.files.upload_and_poll(
file_path="any_file.md",
purpose=FilePurpose.AGENTS
)
print(f"Uploaded: {uploaded_file.id}")
# Cleanup
client.files.delete(file_id=uploaded_file.id)
client.close()- Run the following async script — it fails:
import asyncio
from azure.ai.agents.aio import AgentsClient
from azure.ai.agents.models import FilePurpose
from azure.identity import DefaultAzureCredential
async def main():
client = AgentsClient(
endpoint="https://<endpoint>.services.ai.azure.com/api/projects/<project>",
credential=DefaultAzureCredential()
)
# ❌ This raises DecodeError
uploaded_file = await client.files.upload_and_poll(
file_path="any_file.md",
purpose=FilePurpose.AGENTS
)
asyncio.run(main())Same endpoint, same credentials, same file, same SDK version — only difference is sync vs async client.
Expected behavior
The async files.upload_and_poll() should return a valid FileInfo object with a .id field, identical to the sync version's behavior.
Additional context
Full async traceback:
Traceback (most recent call last):
File ".../azure/core/pipeline/policies/_universal.py", line 618, in deserialize_from_text
return json.loads(data_as_str)
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The above exception was the direct cause of the following exception:
File ".../azure/ai/agents/aio/operations/_patch.py", line 1563, in upload_and_poll
uploaded_file = await self.upload(file_path=file_path, purpose=purpose, **kwargs)
File ".../azure/ai/agents/aio/operations/_patch.py", line 1435, in upload
return await super()._upload_file(body={"file": file_content, "purpose": purpose}, **kwargs)
File ".../azure/ai/agents/aio/operations/_operations.py", line 2411, in _upload_file
pipeline_response: PipelineResponse = await self._client._pipeline.run(...)
...
File ".../azure/core/pipeline/policies/_universal.py", line 728, in on_response
response.context[self.CONTEXT_NAME] = self.deserialize_from_http_generics(...)
File ".../azure/core/pipeline/policies/_universal.py", line 690, in deserialize_from_http_generics
return cls.deserialize_from_text(response.text(encoding), mime_type, response=response)
File ".../azure/core/pipeline/policies/_universal.py", line 620, in deserialize_from_text
raise DecodeError(...)
azure.core.exceptions.DecodeError: JSON is invalid: Expecting value: line 1 column 1 (char 0)
Content: <binary garbage bytes — appears to be compressed/undecoded response body>
The Content: output in the error shows raw binary data, suggesting the async transport is returning the response body without decompression (gzip/deflate) before ContentDecodePolicy attempts JSON parsing.
Impact: This bug makes the async AgentsClient unusable for any file upload operations, blocking files.upload(), files.upload_and_poll(), and any downstream vector store workflows in async applications (e.g. FastAPI, aiohttp-based services).