virattt/ai-hedge-fund · error · ValueError
No v2 client for {provider} (model {model}). Supported: {',
Error message
No v2 client for {provider} (model {model}). Supported: {', '.join(sorted(SUPPORTED_PROVIDERS))}. What it means
Raised by make_llm (hedge_fund/llm/client.py:105) when the resolved provider has no v2 chat client implementation. The provider comes from provider_for(model) — unlisted model ids default to Anthropic — and is checked against SUPPORTED_PROVIDERS (Anthropic, OpenAI, xAI, DeepSeek, Google, Kimi). Since the supported set currently equals the whole registry, hitting this means provider_for returned something unexpected (or the registry grew without a transport).
Source
Thrown at hedge_fund/llm/client.py:105
model: str | None = None,
timeout: float = 60.0,
max_tokens: int = 4096,
on_token: TokenListener = None,
) -> ChatLLM:
"""Build the client for a model id, routed by the registry's provider.
The id comes from the caller, else HEDGE_FUND_LLM_MODEL, else DEFAULT_MODEL — the
same seam the TUI's picker writes to. Raises with the name of the missing
environment variable, because that is the only thing the user can act on.
"""
model = model or os.environ.get("HEDGE_FUND_LLM_MODEL") or DEFAULT_MODEL
provider = provider_for(model)
if provider is None:
# Unlisted ids still work: a model newer than the registry should not
# need a code change. Anthropic is the default transport.
provider = "Anthropic"
if not is_supported(provider):
raise ValueError(
f"No v2 client for {provider} (model {model}). "
f"Supported: {', '.join(sorted(SUPPORTED_PROVIDERS))}."
)
api_key = _require_key(provider)
if provider == "Anthropic":
from langchain_anthropic import ChatAnthropic
chat = ChatAnthropic(model=model, api_key=api_key, timeout=timeout,
max_retries=1, max_tokens=max_tokens)
elif provider == "OpenAI":
from langchain_openai import ChatOpenAI
chat = ChatOpenAI(model=model, api_key=api_key, timeout=timeout,
max_retries=1, base_url=os.getenv("OPENAI_API_BASE"))
elif provider == "DeepSeek":
from langchain_deepseek import ChatDeepSeek
chat = ChatDeepSeek(model=model, api_key=api_key, timeout=timeout,
max_retries=1)View on GitHub (pinned to eff8a7320f)
Solutions
- Set HEDGE_FUND_LLM_MODEL to a known model (default 'claude-sonnet-5') or pass model= explicitly with a supported id from the registry.
- If you need the unsupported provider, add the langchain transport branch for it in make_llm and ensure it's in PROVIDER_ENV_VARS/SUPPORTED_PROVIDERS — then the check passes.
- Inspect provider_for(model) for your exact id to see which provider it resolves to; the error names both provider and model.
Example fix
# before os.environ["HEDGE_FUND_LLM_MODEL"] = "mistral-large" chat = make_llm() # ValueError: No v2 client for ... # after os.environ["HEDGE_FUND_LLM_MODEL"] = "claude-sonnet-5" chat = make_llm()
Defensive patterns
Strategy: validation
Validate before calling
from hedge_fund.llm.registry import SUPPORTED_PROVIDERS, provider_for
def model_is_runnable(model_id: str) -> bool:
provider = provider_for(model_id) or "Anthropic" # same default as make_llm
return provider in SUPPORTED_PROVIDERS Type guard
from hedge_fund.llm.registry import SUPPORTED_PROVIDERS, provider_for
def resolves_to_supported_provider(model_id: str) -> bool:
p = provider_for(model_id)
return (p or "Anthropic") in SUPPORTED_PROVIDERS Try / catch
try:
chat = make_llm(model=model_id)
except ValueError as e:
if "No v2 client" in str(e):
raise SystemExit(
f"model {model_id!r} has no transport; pick one of the registry models"
) from e
raise Prevention
- Set HEDGE_FUND_LLM_MODEL to an id from the shipped registry rather than free-typing ids.
- Validate the model id against provider_for()/SUPPORTED_PROVIDERS at app startup, not at first LLM call.
- After upgrading, re-run any smoke test that constructs the LLM — registries and transports drift together.
When it happens
Trigger: Setting HEDGE_FUND_LLM_MODEL (or passing model=) to an id that provider_for maps to a provider not in {Anthropic, OpenAI, xAI, DeepSeek, Google, Kimi}; a custom/extended registry entry added without a corresponding client branch in make_llm; a TUI picker selection of a provider row that is shown but not backed by a transport (the registry comment notes such rows should be non-selectable).
Common situations: New model id added to the registry file before the transport existed; HEDGE_FUND_LLM_MODEL left over from a fork that supported a provider (e.g. 'Mistral') this build doesn't; env var pointing at a typo'd model string that maps oddly.
Related errors
- {env_var} not found. Set it in your .env to use {provider} m
- unknown rebalance cadence {cadence!r}
- duplicate strategy names: {sorted(duplicates)}
- unknown model {m.name!r} in strategy {strategy.name!r}; avai
- no JSON object found in response: {text[:200]!r}
AI-assisted analysis of virattt/ai-hedge-fund@eff8a7320f (2026-08-15).
Data as JSON: /api/errors/d10bb570745465aa.
Report an issue: GitHub.