we-promise/sure · error · Provider::Anthropic::Error
Model does not support PDF processing: #{effective_model}
Error message
Model does not support PDF processing: #{effective_model} What it means
process_pdf raises Error unless supports_pdf_processing?(model:) is true. On the standard API (no custom base_url) that method checks the model ID against VISION_CAPABLE_MODEL_PREFIXES; only models starting with one of those prefixes are considered able to handle native PDF document blocks. Custom endpoints (custom_endpoint?) bypass the gate entirely because proxies validate model support themselves.
Source
Thrown at app/models/provider/anthropic.rb:160
family: family
).enhance_merchants
upsert_langfuse_trace(trace: trace, output: result.map(&:to_h))
result
end
end
def supports_pdf_processing?(model: @default_model)
return true if custom_endpoint?
VISION_CAPABLE_MODEL_PREFIXES.any? { |prefix| model.to_s.start_with?(prefix) }
end
def process_pdf(pdf_content:, model: "", family: nil)
with_provider_response do
effective_model = model.presence || @default_model
raise Error, "Model does not support PDF processing: #{effective_model}" unless supports_pdf_processing?(model: effective_model)
trace = create_langfuse_trace(
name: "anthropic.process_pdf",
input: { pdf_size: pdf_content&.bytesize }
)
result = PdfProcessor.new(
client,
model: effective_model,
pdf_content: pdf_content,
langfuse_trace: trace,
family: family
).process
upsert_langfuse_trace(trace: trace, output: result.to_h)
result
endView on GitHub (pinned to e69894adb9)
Solutions
- Switch to a vision-capable Claude model (a current Sonnet/Opus ID) in your Anthropic provider settings — those match the allowed prefixes.
- If you are routing through a compatible gateway whose models do support PDFs, configure the custom base_url so custom_endpoint? bypasses the prefix gate.
- If the model genuinely supports PDFs on the direct API but the prefix list is stale, update VISION_CAPABLE_MODEL_PREFIXES in the provider and add a test.
Example fix
# before provider.process_pdf(pdf_content: pdf, model: "claude-2") # => Model does not support PDF processing: claude-2 # after provider.process_pdf(pdf_content: pdf, model: "claude-sonnet-4-6") # or gate first: if provider.supports_pdf_processing?(model: chosen_model) provider.process_pdf(pdf_content: pdf, model: chosen_model) end
Defensive patterns
Strategy: type-guard
Validate before calling
if provider.supports_pdf_processing?(model: chosen_model)
provider.process_pdf(pdf_content: pdf, model: chosen_model)
else
render_error("#{chosen_model} cannot process PDFs; pick a vision-capable Claude model")
end Type guard
def pdf_capable?(provider, model) provider.supports_pdf_processing?(model: model) end # true even on custom endpoints (gate bypassed); false for non-vision prefix IDs on the direct API
Try / catch
begin provider.process_pdf(pdf_content: pdf, model: model) rescue Provider::Anthropic::Error => e # config error: fix model, don't retry flash.now[:alert] = e.message end
Prevention
- Restrict the settings model picker to known vision-capable models rather than free text.
- Call supports_pdf_processing? before showing/enabling PDF upload UI.
- Keep VISION_CAPABLE_MODEL_PREFIXES current when new model generations ship.
When it happens
Trigger: Calling process_pdf with model: "" falling through to a @default_model whose ID doesn't start with any vision-capable prefix — e.g. an old/new/typo'd model ID configured in settings while using api.anthropic.com directly. The check runs before the request, so no API call is wasted.
Common situations: Settings offer a free-text model field and the user enters a legacy (claude-2), non-vision, or misspelled model; Anthropic ships a new model generation before the prefix list is updated; a model ID copied from a proxy gateway (with gateway-specific naming) used against the direct API.
Related errors
- PDF content is required
- PDF exceeds Anthropic's 32 MB limit (#{pdf_content.bytesize}
- Model did not invoke #{TOOL_NAME}
- PDF content is required
- PDF is too large (#{pdf_content.bytesize} bytes); base64-enc
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/d297fa36540185e7.
Report an issue: GitHub.