Skip to content

fix: exclude null file_id from input_image payload to prevent 400 sch…#5125

Open
Serjbory wants to merge 2 commits intomicrosoft:mainfrom
Serjbory:fix/issue-5120
Open

fix: exclude null file_id from input_image payload to prevent 400 sch…#5125
Serjbory wants to merge 2 commits intomicrosoft:mainfrom
Serjbory:fix/issue-5120

Conversation

@Serjbory
Copy link
Copy Markdown

@Serjbory Serjbory commented Apr 6, 2026

…ema error (#5120)

Motivation and Context

Using Content.from_uri() with a base64 data URI to send images via FoundryChatClient (Responses API path) results in a 400 error: "The provided data does not match the expected schema".

This is a regression in 1.0.0 that breaks all inline image inputs through the Responses API client.

Description

The _prepare_content_for_openai method in RawOpenAIChatClient unconditionally included "file_id": None in the input_image payload dict. Because the framework passes raw dicts (not Pydantic models) to the OpenAI SDK, None values are not stripped during serialization — None becomes null on the wire:

{"type": "input_image", "image_url": "data:image/jpeg;base64,...", "detail": "auto", "file_id": null}

The API expects file_id to be a string when present. Sending null violates the schema and produces the 400 error.

Fix: Only include file_id in the dict when it has an actual value. Updated the corresponding test assertion from file_id is None to file_id not in result.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@ManniArora
Copy link
Copy Markdown

Thanks for pushing this fix!

Copy link
Copy Markdown
Contributor

@giles17 giles17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 94%

✓ Correctness

The fix correctly addresses the issue of sending "file_id": null to APIs (like Azure AI Foundry) that reject null values in the request payload. The implementation properly builds the base dict without file_id, then conditionally adds it only when a non-None value is present. The test assertion is correctly updated to match the new behavior ("file_id" not in result instead of result["file_id"] is None). The Any type used in the new dict[str, Any] annotation is already imported. The a2a test changes are purely cosmetic reformatting with no functional impact. No correctness issues found.

✓ Security Reliability

This PR fixes a reliability issue where "file_id": null was always included in the image content payload sent to the OpenAI/Azure AI Foundry Responses API, causing request rejections from services with strict schema validation. The fix conditionally includes file_id only when it has a non-None value, which is the correct approach and consistent with how filename is handled for input_file content (lines 1360-1361 in the existing code). The test updates correctly verify the new behavior. The a2a test changes are whitespace-only reformatting with no functional impact. No security or reliability concerns found.

✗ Test Coverage

The code change correctly fixes the bug where file_id: null was being sent in API payloads. The existing test at line 2274 is properly updated to assert "file_id" not in result instead of result["file_id"] is None, and the positive test case (line 2267) still validates that file_id is included when provided. However, there is a missing test for the edge case where additional_properties exists but does not contain a file_id key (e.g., {"detail": "high"} without file_id), which is distinct from having no additional_properties at all. The a2a test changes are purely formatting (no behavioral changes).

✓ Design Approach

The core fix correctly addresses the root cause: "file_id": null was always serialized into the Responses API payload, causing rejection by stricter API validators (e.g., Azure AI Foundry). The fix conditionally includes file_id only when it has a real value, consistent with how filename and status are handled elsewhere in the same function. The test update correctly reflects the new contract. The a2a test changes are pure cosmetic reformatting with no behavioral impact. No design-level concerns remain.

Suggestions

  • Add a test case for image content with additional_properties that has other keys but no file_id (e.g., additional_properties={"detail": "high"}). This exercises the content.additional_properties.get("file_id") returning None path where additional_properties is not None but file_id is absent — a distinct code path from the additional_properties is None case already tested.

Automated review by giles17's agents

@markwallace-microsoft
Copy link
Copy Markdown
Contributor

markwallace-microsoft commented Apr 6, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/openai/agent_framework_openai
   _chat_client.py85912785%520–523, 527–528, 533–534, 544–545, 552, 567–573, 594, 602, 625, 743, 842, 901, 903, 905, 907, 973, 987, 1067, 1077, 1082, 1125, 1202, 1232, 1289, 1383, 1388, 1392–1394, 1398–1399, 1465, 1494, 1500, 1510, 1516, 1521, 1527, 1532–1533, 1594, 1616–1617, 1632–1633, 1651–1652, 1693–1696, 1858, 1896–1897, 1913, 1915, 1993–2001, 2123, 2158, 2173, 2193–2203, 2216, 2227–2231, 2245, 2259–2270, 2279, 2311–2314, 2322–2323, 2325–2327, 2341–2343, 2353–2354, 2360, 2375
TOTAL27061318888% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
5373 20 💤 0 ❌ 0 🔥 1m 24s ⏱️

@Serjbory
Copy link
Copy Markdown
Author

Serjbory commented Apr 6, 2026

@giles17 thx for the review. I've added test for the mentioned edge case

Sign up for free to 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.

4 participants