we-promise/sure · error · Provider::Anthropic::Error
PDF content is required
Error message
PDF content is required
What it means
Provider::Anthropic::BankStatementExtractor#extract raises "PDF content is required" when pdf_content is blank (nil or empty string). The extractor sends the raw PDF bytes as a native document block to the Messages API, so empty content has nothing to send; the guard runs before the API call, the Langfuse span, and size check.
Source
Thrown at app/models/provider/anthropic/bank_statement_extractor.rb:20
include Provider::Anthropic::Concerns::UsageRecorder
TOOL_NAME = "report_bank_statement".freeze
# Mirrors Provider::Anthropic::PdfProcessor::MAX_PDF_BYTES.
MAX_PDF_BYTES = 32 * 1024 * 1024
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 extract
raise Provider::Anthropic::Error, "PDF content is required" if pdf_content.blank?
if pdf_content.bytesize > MAX_PDF_BYTES
raise Provider::Anthropic::Error,
"PDF exceeds Anthropic's 32 MB limit (#{pdf_content.bytesize} bytes)"
end
span = langfuse_trace&.span(name: "extract_bank_statement_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 }
)View on GitHub (pinned to e69894adb9)
Solutions
- Fix the caller to pass actual binary content (pdf.download / File.binread(path)), not a path or File handle.
- Guard upstream: verify the uploaded statement has non-zero bytes before enqueuing the extraction job.
- If the attachment itself is empty, re-import/re-upload the statement.
Example fix
# before extractor.extract # pdf_content came from statement.file.path (a String path) # => PDF content is required # after extractor = BankStatementExtractor.new(client:, model:, pdf_content: statement.file.download) extractor.extract
Defensive patterns
Strategy: validation
Validate before calling
pdf_bytes = statement.file.download
if pdf_bytes.blank?
return error("Statement file is empty — re-upload")
end
extractor.extract # constructed with pdf_content: pdf_bytes Try / catch
begin extractor.extract rescue Provider::Anthropic::Error => e # input problem: re-upload, don't retry statement.mark_import_failed(reason: e.message) end
Prevention
- Validate attachment presence and non-zero size at upload time (model validation).
- Always pass bytes (.download / File.binread), never paths or File objects.
- Fail the import record with a clear reason instead of raising into the job.
When it happens
Trigger: Extract is called with pdf_content: nil — an upload whose file read returned nil, a statement record with an empty attachment, or an upstream pipeline that passes the filename instead of contents.
Common situations: Controller/job reads the attachment before it finished uploading; tempfile closed and re-read returns nil; code passes pdf_path or File object where bytes are expected; statement import from a URL that downloaded zero bytes.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- PDF exceeds Anthropic's 32 MB limit (#{pdf_content.bytesize}
- Model did not invoke #{TOOL_NAME}
- PDF content is required
- No categories available for auto-categorization
- Model does not support PDF processing: #{effective_model}
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/231c63ffa6ae2432.
Report an issue: GitHub.