we-promise/sure · error · Setting::ValidationError

Anthropic Model is required when a custom Base URL is set.

Error message

Anthropic Model is required when a custom Base URL is set.

What it means

A custom Anthropic-compatible endpoint needs an explicit model because Provider::Anthropic raises without one (there is no default model to fall back to when you bypass the official API). The controller validates the pair together: it computes effective_model from the submitted anthropic_model param if present, otherwise from the stored Setting.anthropic_model, and raises Setting::ValidationError with '.anthropic_model_required_for_base_url' when it is blank while a base URL is being set. Using the submitted value means clearing the model field in the same save is caught too, not just an empty stored value.

Source

Thrown at app/controllers/settings/hostings_controller.rb:198

      raw_base_url = hosting_params[:anthropic_base_url].to_s.strip
      if raw_base_url.blank?
        Setting.anthropic_base_url = nil
      else
        parsed = URI.parse(raw_base_url) rescue nil
        unless parsed.is_a?(URI::HTTP)
          raise Setting::ValidationError, t(".invalid_anthropic_base_url")
        end
        # A custom Anthropic-compatible endpoint requires a model — Provider::Anthropic
        # raises without one. Validate the pair together (mirrors the OpenAI branch), using
        # the submitted model when present so a blanked model field is caught too.
        effective_model =
          if hosting_params.key?(:anthropic_model)
            hosting_params[:anthropic_model].to_s.strip
          else
            Setting.anthropic_model.to_s.strip
          end
        if effective_model.blank?
          raise Setting::ValidationError, t(".anthropic_model_required_for_base_url")
        end
        Setting.anthropic_base_url = raw_base_url
      end
    end

    if hosting_params.key?(:anthropic_model)
      Setting.anthropic_model = hosting_params[:anthropic_model].presence
    end

    if hosting_params.key?(:llm_provider)
      provider = hosting_params[:llm_provider].to_s
      if %w[openai anthropic].include?(provider)
        Setting.llm_provider = provider
      end
    end

    LLM_NUMERIC_MINIMUMS.each do |key, minimum|
      next unless hosting_params.key?(key)

View on GitHub (pinned to e69894adb9)

Solutions

  1. Fill in both fields: set anthropic_model to a model the endpoint serves (e.g. claude-3-5-sonnet-latest or the proxy's model alias) together with the base URL
  2. If you meant to clear the custom endpoint, clear anthropic_base_url instead — a blank base URL is stored as nil and skips the model requirement entirely
  3. Check Setting.anthropic_model in the Rails console to see what the fallback would resolve to before saving
  4. If the pair keeps rejecting, verify with: m = params.key?(:anthropic_model) ? params[:anthropic_model] : Setting.anthropic_model; raise if m.strip.blank?

Example fix

# before
Setting.anthropic_base_url = "http://localhost:4000"   # model left blank / only whitespace
# => Setting::ValidationError: Anthropic Model is required when a custom Base URL is set.

# after
Setting.anthropic_base_url = "http://localhost:4000"
Setting.anthropic_model     = "claude-3-5-haiku-latest"
Defensive patterns

Strategy: validation

Validate before calling

# Before enabling a custom Anthropic endpoint
url = params[:anthropic_base_url].to_s.strip
model = params.key?(:anthropic_model) ? params[:anthropic_model].to_s.strip : Setting.anthropic_model.to_s.strip

if url.present? && model.blank?
  # block the save: pair is incomplete
  raise "anthropic_model required with base_url"
end

Type guard

def complete_anthropic_pair?(url, model)
  url.to_s.strip.empty? || !model.to_s.strip.empty?
end

Try / catch

rescue Setting::ValidationError => e
  # keep both form values rendered so the user finishes the pair
  render :edit, status: :unprocessable_entity
end

Prevention

When it happens

Trigger: Submitting anthropic_base_url with an empty anthropic_model field on a fresh install (nothing stored, nothing submitted); submitting both fields but the model field contains only whitespace; submitting the base URL while a previously stored model exists but sending anthropic_model: "" in the same request (blanked field is caught); a PATCH that sets only the base URL after the model was previously cleared.

Common situations: Self-hosters switching from the official Anthropic API to a proxy (LiteLLM, OpenRouter-style gateway) and filling in the URL first, intending to pick a model later; environment parity issues where staging had a model saved but production does not; form serialization dropping empty fields so the server sees key present but blank.

Related errors


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