Skip to content

fix(models): convert input_file items that reference a file_id on the Chat Completions path - #4295

Merged
seratch merged 1 commit into
openai:mainfrom
hsusul:fix/chatcmpl-input-file-file-id
Aug 8, 2026
Merged

fix(models): convert input_file items that reference a file_id on the Chat Completions path#4295
seratch merged 1 commit into
openai:mainfrom
hsusul:fix/chatcmpl-input-file-file-id

Conversation

@hsusul

@hsusul hsusul commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

The Chat Completions converter (Converter.extract_all_content) rejected any
input_file content part that did not carry inline file_data, raising
UserError("Only file_data is supported for input_file ..."). But the Chat
Completions file content part (openai.types.chat...FileFile) accepts either
inline file_data or a reference to an uploaded file_id, so an
input_file that references a file_id is fully representable and should be
converted rather than rejected.

This also fixes an internal inconsistency: the SDK's own
ToolOutputFileContent emits file_id-only input_file items (see
ItemHelpers._convert_single_tool_output_pydantic_model). A function tool that
returns ToolOutputFileContent(file_id=...) therefore produced a tool output
that the SDK's own Chat Completions converter refused to convert on the next
turn.

extract_all_content is called on tool outputs regardless of
preserve_tool_output_all_content (the non-preserve branch still calls it
before filtering to text), so this UserError aborts the run instead of letting
the caller degrade the output.

Fix (minimal): prefer inline file_data when present, otherwise fall back
to file_id. Only raise when neither is present. A file_url remains
unrepresentable on Chat Completions and still raises, and existing file_data
behavior (including the file_data-takes-precedence and optional filename
handling) is unchanged.

Before:

Converter.extract_all_content([{"type": "input_file", "file_id": "file-abc123"}])
# UserError: Only file_data is supported for input_file {...}

After:

Converter.extract_all_content([{"type": "input_file", "file_id": "file-abc123"}])
# [{"type": "file", "file": {"file_id": "file-abc123"}}]

Root cause

The input_file branch guarded on file_data only and raised for everything
else, predating (and never updated for) the file_id field that both the
Responses input_file param and the Chat Completions file part support.

Why minimal

  • One converter branch changed; no new abstractions or public API changes.
  • file_data path, file_data-over-file_id precedence, filename
    forwarding, and prompt-cache-breakpoint copying are all preserved.
  • file_url is intentionally left unsupported (not representable on Chat
    Completions) and still raises.

Test plan

Added three focused unit tests in
tests/models/test_openai_chatcompletions_converter.py:

  • test_extract_all_content_supports_input_file_file_id — converts a
    file_id-only input_file (fails on main, passes here).
  • test_extract_all_content_prefers_input_file_data_over_file_idfile_data
    still wins when both are present.
  • test_extract_all_content_rejects_input_file_without_data_or_id — neither
    present still raises UserError.

Validation commands (all pass):

  • uv run pytest tests/models/test_openai_chatcompletions_converter.py -q → 51 passed
  • uv run pytest tests/models -q → 695 passed
  • uv run pytest -q → 7161 passed, 39 skipped
  • uv run ruff check . → All checks passed
  • uv run ruff format --check . → clean
  • uv run mypy . --exclude site → Success (852 source files)
  • uv run pyright → 0 errors

Compatibility: behavior only broadens (previously-raising inputs now convert);
no changes to items that already converted. No dependency or config changes.

Issue number

N/A (no OpenAI API key or live service required to reproduce).

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass
  • If using Codex, I've run /review before submitting this PR

… Chat Completions path

The Chat Completions file content part accepts either inline file_data or an
uploaded file_id, and the SDK's own ToolOutputFileContent emits file-id-only
input_file items. The converter rejected any input_file without file_data, so a
user message or tool output referencing an uploaded file raised UserError even
though it is representable. Fall back to file_id when file_data is absent.
@seratch seratch added this to the 0.20.x milestone Aug 8, 2026
@seratch
seratch merged commit 5f5c773 into openai:main Aug 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants