we-promise/sure · error · Provider::Anthropic::Error
PDF is too large (#{pdf_content.bytesize} bytes); base64-enc
Error message
PDF is too large (#{pdf_content.bytesize} bytes); base64-encoded it would exceed Anthropic's 32 MB request limit What it means
PdfProcessor#process raises when pdf_content.bytesize exceeds MAX_PDF_BYTES, which is deliberately lower than 32 MiB — (MAX_REQUEST_BYTES - REQUEST_ENVELOPE_BYTES) * 3 / 4 — because this processor base64-encodes the PDF (4/3 expansion) inside the JSON request envelope. The pre-check guarantees the final request stays under Anthropic's 32 MB API limit.
Source
Thrown at app/models/provider/anthropic/pdf_processor.rb:30
# vain (peak heap before the API would reject it).
MAX_REQUEST_BYTES = 32 * 1024 * 1024
REQUEST_ENVELOPE_BYTES = 1 * 1024 * 1024
MAX_PDF_BYTES = (MAX_REQUEST_BYTES - REQUEST_ENVELOPE_BYTES) * 3 / 4
attr_reader :client, :model, :pdf_content, :langfuse_trace, :family
def initialize(client, model:, pdf_content:, langfuse_trace: nil, family: nil)
@client = client
@model = model
@pdf_content = pdf_content
@langfuse_trace = langfuse_trace
@family = family
end
def process
raise Provider::Anthropic::Error, "PDF content is required" if pdf_content.blank?
if pdf_content.bytesize > MAX_PDF_BYTES
raise Provider::Anthropic::Error,
"PDF is too large (#{pdf_content.bytesize} bytes); base64-encoded it would exceed Anthropic's 32 MB request limit"
end
span = langfuse_trace&.span(name: "process_pdf_api_call", input: {
model: model,
pdf_size: pdf_content&.bytesize
})
response = client.messages.create(
model: model,
max_tokens: max_tokens,
system_: instructions,
messages: [ { role: "user", content: user_content } ],
tools: [ output_tool ],
tool_choice: { type: "tool", name: TOOL_NAME, disable_parallel_tool_use: true }
)
parsed = extract_tool_input(response)View on GitHub (pinned to e69894adb9)
Solutions
- Compress or split the PDF so raw bytes fit the effective base64-adjusted cap (downsample scans, export fewer pages).
- If you add an upload size guard, size it to the PdfProcessor limit (the stricter one), not the raw 32 MiB extractor limit.
- Retry processing after re-saving the PDF with optimization (qpdf/ghostscript) to shrink it.
Example fix
# before
result = provider.process_pdf(pdf_content: big_pdf)
# => PDF is too large (27053268 bytes); base64-encoded it would exceed Anthropic's 32 MB request limit
# after
if big_pdf.bytesize > Provider::Anthropic::PdfProcessor::MAX_PDF_BYTES
return error("Compress or split the PDF before processing")
end
result = provider.process_pdf(pdf_content: big_pdf) Defensive patterns
Strategy: validation
Validate before calling
limit = Provider::Anthropic::PdfProcessor::MAX_PDF_BYTES
if pdf.bytesize > limit
return error("PDF too large after base64 encoding; compress or split it")
end
provider.process_pdf(pdf_content: pdf) Try / catch
begin processor.process rescue Provider::Anthropic::Error => e doc.mark_failed(reason: e.message) end
Prevention
- Size upload limits against the base64-adjusted cap, not the raw 32 MiB number.
- Compress or split scanned PDFs before processing.
- Remember this processor's effective limit is ~3/4 of 32 MiB minus envelope overhead.
When it happens
Trigger: Processing a PDF whose raw size is large enough that its base64 form plus request envelope would exceed 32 MB (roughly >24 MiB raw depending on envelope math); fires before client.messages.create, so no API call is made.
Common situations: Scanned/image-heavy PDFs; yearly brokerage statements; uploads that passed an app-level 32 MB check tuned for the bank-statement extractor (which sends raw bytes, not base64) but exceed this processor's tighter effective limit.
Related errors
- PDF exceeds Anthropic's 32 MB limit (#{pdf_content.bytesize}
- PDF content is required
- Model did not invoke #{TOOL_NAME}
- Model does not support PDF processing: #{effective_model}
- PDF content is required
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/be8483d7491f26a4.
Report an issue: GitHub.