Skip to content

Send file DataContent as a data URI in OpenAI chat requests#559

Open
PratikDhanave wants to merge 1 commit into
microsoft:mainfrom
PratikDhanave:fix-openai-chat-file-data-uri
Open

Send file DataContent as a data URI in OpenAI chat requests#559
PratikDhanave wants to merge 1 commit into
microsoft:mainfrom
PratikDhanave:fix-openai-chat-file-data-uri

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

In buildMessageParam (chat completions, RoleUser), a non-image/non-audio DataContent (e.g. a PDF) was sent with the raw base64 payload:

default:
    contents = append(contents, openai.FileContentPart(openai.ChatCompletionContentPartFileFileParam{
        FileData: openai.String(c.Data),   // raw base64 — missing the data-URI prefix
        Filename: openai.String(c.Name),
    }))

DataContent.Data is the raw base64 (see message/content.go), but the OpenAI Chat Completions API requires file_data to be a full data URI — data:<mediatype>;base64,<data> (per OpenAI’s PDF-files guide: "file_data": "data:application/pdf;base64,${base64String}"). Sent as raw base64, the file is rejected/mishandled.

This is the outlier:

  • The image branch two cases up already uses c.URI() (chat.go:410).
  • The Responses provider sends file_data as c.URI() (responses.go:509), asserted in responses_test.go.
  • DataContent.URI() returns exactly data:<mediatype>;base64,<data>.

No test covered the chat non-image DataContent path (only the image case), so it went unnoticed.

Fix

FileData: openai.String(c.URI()). The adjacent audio branch keeps raw c.Data — the input_audio API genuinely expects raw base64, so it is correct and left unchanged.

Test

TestChatDataContentMessage_File_NonStreaming sends a user message with a PDF DataContent and asserts the request body’s file_data is data:application/pdf;base64,cGRmZGF0YQ==. It fails on the old code (raw cGRmZGF0YQ==) and passes with the fix.

The Chat Completions user-message builder put the raw base64 payload in a
file content part's file_data, but the API expects a full data URI
(data:<mediatype>;base64,<data>). The image branch in the same function
already uses c.URI(), and the Responses provider sends file_data as
c.URI() too — the chat file branch was the outlier, so PDFs and other
non-image/non-audio files were rejected or mishandled.

Use c.URI() for the file part. The adjacent audio branch keeps raw base64,
which the input_audio API genuinely expects.
Copilot AI review requested due to automatic review settings July 19, 2026 13:28
@PratikDhanave
PratikDhanave requested a review from a team as a code owner July 19, 2026 13:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes how message.DataContent files (non-image/non-audio, e.g. PDFs) are serialized into OpenAI Chat Completions requests by sending file_data as a full RFC 2397 data URI (data:<mediatype>;base64,<data>), aligning with the existing image handling and the Responses provider behavior.

Changes:

  • Update Chat Completions message building to use DataContent.URI() for file_data in the non-image/non-audio file branch.
  • Add a non-streaming chat test that asserts PDF DataContent is sent as a data URI (not raw base64).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
provider/openaiprovider/chat.go Switch non-image/non-audio DataContent file_data from raw base64 to c.URI() (data URI).
provider/openaiprovider/chat_test.go Add coverage ensuring PDF DataContent is emitted as a data URI in chat requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants