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
    end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Switch to a vision-capable Claude model (a current Sonnet/Opus ID) in your Anthropic provider settings — those match the allowed prefixes.
  2. 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.
  3. 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

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


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/d297fa36540185e7. Report an issue: GitHub.