we-promise/sure · error · StandardError
No LLM provider configured that supports model '#{requested_
Error message
No LLM provider configured that supports model '#{requested_model}'.\n\nAvailable providers:\n#{provider_details}\n\nPlease either:\n 1. Use a supported model from the list above, or\n 2. Configure a provider that supports '#{requested_model}' in settings. What it means
Assistant::Builtin#respond_to resolves which LLM provider to use for the chat's requested model via get_model_provider(message.ai_model); if no configured provider (OpenAI / Anthropic settings) supports that model, it builds a diagnostic message — "No LLM provider configured that supports model 'X'" plus the list of available providers with their models — and raises StandardError. The message is intentionally actionable: it tells the user to either pick a supported model or configure a provider in settings.
Source
Thrown at app/models/assistant/builtin.rb:25
class << self
def for_chat(chat)
config = config_for(chat)
new(chat, instructions: config[:instructions], functions: config[:functions])
end
end
def initialize(chat, instructions: nil, functions: [])
super(chat)
@instructions = instructions
@functions = functions
end
def respond_to(message, assistant_message: nil)
assistant_message ||= AssistantMessage.new(chat: chat, content: "", ai_model: message.ai_model)
llm_provider = get_model_provider(message.ai_model)
unless llm_provider
raise StandardError, build_no_provider_error_message(message.ai_model)
end
responder = Assistant::Responder.new(
message: message,
instructions: instructions,
function_tool_caller: function_tool_caller,
llm: llm_provider
)
latest_response_id = chat.latest_assistant_response_id
responder.on(:output_text) do |text|
if assistant_message.content.blank?
Chat.transaction do
assistant_message.append_text!(text)
chat.update_latest_response!(latest_response_id)
end
elseView on GitHub (pinned to e69894adb9)
Solutions
- In the chat, switch the model selector to one listed in the error's "Available providers" section and resend
- Or complete the provider config: Settings > Self-Hosting — add the API key (and base URL/model pair for custom endpoints) for a provider that serves the requested model
- For custom/self-hosted model gateways, ensure the provider's configured model list actually contains the exact string being requested (watch versions/aliases: 'gpt-4o' vs 'gpt-4o-2024-08-06')
- For stale old chats, bulk-update AssistantMessage/chat ai_model to a currently supported model or delete the chats
Example fix
# before message = chat.messages.create!(content: "hi", ai_model: "claude-3-opus-20230101") Assistant::Builtin.new(chat).respond_to(message) # => StandardError: No LLM provider configured that supports model 'claude-3-opus-20230101'. ... # after: use a model from the configured provider's list supported = Assistant::Builtin.new(chat).send(:get_model_provider, "gpt-4o")&.configured_models rescue [] message = chat.messages.create!(content: "hi", ai_model: "gpt-4o") # matches provider config Assistant::Builtin.new(chat).respond_to(message)
Defensive patterns
Strategy: validation
Validate before calling
# Before sending, verify the requested model is served chat = Chat.find(chat_id) provider = Assistant::Builtin.new(chat).send(:get_model_provider, chat.assistant_model) raise "pick a supported model" unless provider # or expose a whitelist endpoint the UI validates against
Type guard
def supported_model?(model_name)
# mirror of get_model_provider's resolution
[ Provider::OpenAI, Provider::Anthropic ].any? do |p|
p.configured? && p.supports_model?(model_name)
end
end Try / catch
begin
Assistant::Builtin.new(chat).respond_to(message)
rescue StandardError => e
if e.message.start_with?("No LLM provider configured")
# e.message lists available models: surface as model-picker options
chat.add_error(e)
else
raise
end
end Prevention
- Restrict the chat model picker to models the current config actually serves
- Migrate old chats' ai_model when retiring/renaming provider models
- Keep provider model lists explicit in settings so custom names are deliberate
- Parse the error's provider list programmatically to offer the user valid replacements
When it happens
Trigger: Sending an assistant message whose ai_model is a model string no provider advertises: provider settings were changed/removed after older chats picked that model; reopening an old conversation whose stored ai_model was retired/renamed (e.g. gpt-4-turbo-preview deprecated); only one provider configured (OpenAI) while the message requests a claude-* model, or vice versa; a typo'd or user-supplied custom model name that doesn't match the provider's configured list; provider configured but its model list setting doesn't include the custom model name.
Common situations: Self-hosters swapping API keys/providers and forgetting old chats keep their original model; upgrading the app retires a model name upstream providers no longer list; users pasting a model name from the internet; partial configuration — API key present but model allowlist updated.
Related errors
- External assistant is not configured. Set the URL and token
- {e.record.errors.full_messages.to_sentence.presence || e.mes
- Anthropic Model is required when a custom Base URL is set.
- %{field} must be a whole number ≥ %{minimum}.
- Your account is not authorized to use the external assistant
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/b567a3e62cf83c54.
Report an issue: GitHub.