{"record":{"id":"be8483d7491f26a4","repo":"we-promise/sure","slug":"pdf-is-too-large-pdf-content-bytesize-bytes","errorCode":null,"errorMessage":"PDF is too large (#{pdf_content.bytesize} bytes); base64-encoded it would exceed Anthropic's 32 MB request limit","messagePattern":"PDF is too large \\(#(.+?) bytes\\); base64-encoded it would exceed Anthropic's 32 MB request limit","errorType":"exception","errorClass":"Provider::Anthropic::Error","httpStatus":null,"severity":"error","filePath":"app/models/provider/anthropic/pdf_processor.rb","lineNumber":30,"sourceCode":"  # vain (peak heap before the API would reject it).\n  MAX_REQUEST_BYTES = 32 * 1024 * 1024\n  REQUEST_ENVELOPE_BYTES = 1 * 1024 * 1024\n  MAX_PDF_BYTES = (MAX_REQUEST_BYTES - REQUEST_ENVELOPE_BYTES) * 3 / 4\n\n  attr_reader :client, :model, :pdf_content, :langfuse_trace, :family\n\n  def initialize(client, model:, pdf_content:, langfuse_trace: nil, family: nil)\n    @client = client\n    @model = model\n    @pdf_content = pdf_content\n    @langfuse_trace = langfuse_trace\n    @family = family\n  end\n\n  def process\n    raise Provider::Anthropic::Error, \"PDF content is required\" if pdf_content.blank?\n    if pdf_content.bytesize > MAX_PDF_BYTES\n      raise Provider::Anthropic::Error,\n            \"PDF is too large (#{pdf_content.bytesize} bytes); base64-encoded it would exceed Anthropic's 32 MB request limit\"\n    end\n\n    span = langfuse_trace&.span(name: \"process_pdf_api_call\", input: {\n      model: model,\n      pdf_size: pdf_content&.bytesize\n    })\n\n    response = client.messages.create(\n      model: model,\n      max_tokens: max_tokens,\n      system_: instructions,\n      messages: [ { role: \"user\", content: user_content } ],\n      tools: [ output_tool ],\n      tool_choice: { type: \"tool\", name: TOOL_NAME, disable_parallel_tool_use: true }\n    )\n\n    parsed = extract_tool_input(response)","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/anthropic/pdf_processor.rb#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nresult = provider.process_pdf(pdf_content: big_pdf)\n# => PDF is too large (27053268 bytes); base64-encoded it would exceed Anthropic's 32 MB request limit\n\n# after\nif big_pdf.bytesize > Provider::Anthropic::PdfProcessor::MAX_PDF_BYTES\n  return error(\"Compress or split the PDF before processing\")\nend\nresult = provider.process_pdf(pdf_content: big_pdf)","handlingStrategy":"validation","validationCode":"limit = Provider::Anthropic::PdfProcessor::MAX_PDF_BYTES\nif pdf.bytesize > limit\n  return error(\"PDF too large after base64 encoding; compress or split it\")\nend\nprovider.process_pdf(pdf_content: pdf)","typeGuard":null,"tryCatchPattern":"begin\n  processor.process\nrescue Provider::Anthropic::Error => e\n  doc.mark_failed(reason: e.message)\nend","preventionTips":["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."],"tags":["anthropic","llm","pdf","file-size-limit","base64","document-processing"],"backgroundTag":"payload-too-large","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}