I’m developing an application that analyzes PDF files using OpenAI’s Chat Completion API. I’m experiencing inconsistent results that are causing difficulties and would appreciate any help.
Problem:
When uploading the same PDF file and requesting analysis with the same code, sometimes the analysis works properly, while other times I receive responses like “Please upload a PDF” or “Please attach a file.”
This issue shows an unpredictable pattern where out of 10 requests with the same PDF, some succeed while others fail.
Details:
API Used: chat.completions.create endpoint (GPT-4o model)
Code Example:
Copy# Step 1: Upload PDF file
with open(pdf_path, "rb") as f:
file_response = client.files.create(file=f, purpose="user_data")
file_id = file_response.id
# Step 2: Ask question with Chat Completion
completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{
"type": "file",
"file": {
"file_id": file_id,
},
},
{
"type": "text",
"text": "Please analyze the content of this PDF.",
},
],
}
],
)
Solutions Attempted:
Added delay time (sleep()) after file upload to allow for processing
Implemented retry logic
Used different API keys
Created new OpenAI projects
However, while these methods may provide temporary solutions, the issue continues to occur intermittently.
Questions:
What is the root cause of this inconsistency?
Is this a known issue that OpenAI is aware of?
Are there better ways to solve or mitigate this problem?
Is there more detailed technical documentation on the PDF analysis process?
Any help or insights would be greatly appreciated. Thank you.
I’m seeing the exact same issue. Had a prompt that included the file in base64 format as part of the prompt and the issue cropped up this week where roughly half of the responses from OpenAI indicated a missing file. I tried changing the prompt to upload the file and reference the file id (as you’re doing) and still see the same issue. I’m logging all my requests and can confirm the exact same prompts using the exact same PDF can produce both success and failure cases from the AI.
We’re also seeing this problem. Our first few batches of base64-encoded PDFs processed successfully, but hundreds of subsequent batches failed with ‘no content provided’.
We have not hit the 100GB Org limit. Our full dataset is only ~34 GBs.
Also, A 10GB end-user limit, mentioned here, doesn’t seem to apply - we received no errors. And the ‘no-content’ responses started happening well before we uploaded 10GB of content.
completion = client.beta.chat.completions.parse(
model="gpt-4.1",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "Here is the PDF to extract [redacted] from:"},
{
"role": "user",
"content": [
{
"type": "file",
"file": {
"filename": "file.pdf",
"file_data": f"data:application/pdf;base64,{base64_string}"
},
},
]
}
],
response_format=[redacted] # pydantic structured format
)
This code has strange non-deterministic behavior… usually it works fine but sometimes the model doesn’t seem to see the PDF at all… it just returns some structured format containing “No PDF provided” or something like that. When switching to a different PDF being uploaded, this issue seems to happen more often, compared to just uploading the same PDF 10 times. Maybe it has something to do with query caching? I really don’t think it is my code.
I’m also getting inconsistent behavior with PDF uploads, but it is not regarding the content of the response, but it is in getting a response at all. There are times where parsing a PDF takes just a few seconds, and then times where it takes over two minutes before finally timing out. It is completely non-deterministic, maybe half the time it works to parse things quickly whereas the other half it will time out.
Example code (note that I am using RubyLLM, but this is not the issue):
# Processing example custodial statements
custodial_statement.open(tmpdir: Dir.tmpdir) do |file|
chat = RubyLLM.chat
response = chat.ask(prompt, with: file.path)
# Sometimes returns in ~1 second, other times takes 120+ seconds
end
Example error
8:57:29 web.1 | D, [2025-08-26T08:57:29.843107 #79899] DEBUG -- RubyLLM: request: POST https://api.openai.com/v1/chat/completions
08:57:29 web.1 | D, [2025-08-26T08:57:29.843473 #79899] DEBUG -- RubyLLM: request: {"model":"gpt-4.1","messages":[{"role":"user","content":[{"type":"text","text":" You are given a custodial statement in PDF form for an RIA's client. Your task is to extract two specific values:\n\n 1. **Account Value** – The total current value of the client's account.\n 2. **Fee Charged** – The most recent fee charged to the client.\n\n Instructions:\n - Parse the PDF carefully, even if formatting is irregular (tables, headers, footnotes, etc.).\n - Return ONLY a JSON object with this exact format: {\"account_value\": 10500.45, \"fee_charged\": 250.75}\n - Ensure the numbers are properly parsed as floats (e.g., 10500.45, not \"$10,500.45\" or \"10,500.45 USD\").\n - If either field cannot be found, return null for that field.\n - Do not include any other text, explanations, or commentary - only the JSON.\n"},{"type":"file","file":{"filename":"ActiveStorage-2-20250826-79899-p85y3a.pdf","file_data":"data:application/pdf;base64,data":"[BASE64 DATA]""}}]}],"stream":false,"temperature":0.7}
08:59:30 web.1 | D, [2025-08-26T08:59:30.018313 #79899] DEBUG -- RubyLLM: error: /Users/edizaguirre/.rbenv/versions/3.4.4/lib/ruby/gems/3.4.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:229:in 'Net::BufferedIO#rbuf_fill': Net::ReadTimeout with #<TCPSocket:(closed)> (Faraday::TimeoutError)