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.
Solutions
- 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
- 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
- Check Setting.anthropic_model in the Rails console to see what the fallback would resolve to before saving
- 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
- Treat base URL and model as one unit in forms: disable Save until both are filled
- When clearing the model, clear the base URL in the same action
- Seed a default model via ENV/config for fresh installs that will use a proxy
- Automate checks: a smoke test that calls the provider after saving the pair
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.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Anthropic Base URL must be an http(s) URL.
- {e.record.errors.full_messages.to_sentence.presence ||…
- must be a whole number ≥ .
- {result.error}
- Auth config not loaded: #
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/3cc58d74f1d1abc5.
Report an issue: GitHub.
Appendix: 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)