abi/screenshot-to-code · error · ValueError
Unsupported model: {model.value}
Error message
Unsupported model: {model.value} What it means
ValueError raised at the bottom of create_provider_session when the model is not in OPENAI_MODELS, ANTHROPIC_MODELS, or GEMINI_MODELS. It is the factory's exhaustive-match fallback: any Llm enum value (or raw string coerced by Llm(model)) that no provider branch claims lands here. The f-string interpolates the concrete model value.
Source
Thrown at backend/agent/providers/factory.py:80
prompt_messages=prompt_messages,
tools=serialize_anthropic_tools(canonical_tools),
recorder=recorder,
)
if model in GEMINI_MODELS:
if not gemini_api_key:
raise Exception("Gemini API key is missing.")
client = genai.Client(api_key=gemini_api_key)
return GeminiProviderSession(
client=client,
model=model,
prompt_messages=prompt_messages,
tools=serialize_gemini_tools(canonical_tools),
recorder=recorder,
)
raise ValueError(f"Unsupported model: {model.value}")
View on GitHub (pinned to d026163f58)
Solutions
- Add the new model id to the correct *_MODELS set (openai/anthropic/gemini) in the providers module.
- If it is a genuinely new provider, add a branch in the factory before the final raise.
- Check for spelling drift between the enum value and the set membership (whitespace/case).
Example fix
# before
OPENAI_MODELS = {Llm.GPT_4O}
# after
OPENAI_MODELS = {Llm.GPT_4O, Llm.GPT_4_1} Defensive patterns
Strategy: type-guard
Validate before calling
known = OPENAI_MODELS | ANTHROPIC_MODELS | GEMINI_MODELS
if model not in known:
raise ValueError(f"Model {model} not registered; add it to a provider set") Type guard
def is_supported_model(model: Llm) -> bool:
return model in OPENAI_MODELS or model in ANTHROPIC_MODELS or model in GEMINI_MODELS Try / catch
try:
session = create_provider_session(model=model, ...)
except ValueError as e:
if "Unsupported model" in str(e):
# fall back to a default model or reject the request with 400
... Prevention
- Whenever you add an Llm enum value, immediately register it in the matching provider set — treat enum and sets as one change.
- Filter model dropdowns from the registry sets, never from a hardcoded list.
- Add a unit test asserting every Llm member belongs to exactly one provider set.
When it happens
Trigger: A new model is added to the Llm enum (e.g. in evals/runner.py Llm(model)) but not to the corresponding provider model set, or a raw model string is passed that matches no known family.
Common situations: See trigger scenarios.
Related errors
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/c860f306a1b6eefd.
Report an issue: GitHub.