bytedance/deer-flow · critical · ValueError
No chat models are configured. Please configure at least…
Error message
No chat models are configured. Please configure at least one model in config.yaml.
What it means
ValueError from _resolve_model_name in the lead agent: app_config.models is empty, so there is no default model to fall back to. The agent refuses to build rather than running modelless. This is a configuration error — config.yaml has zero entries under models.
Solutions
- Add at least one full model entry under models: in config.yaml and restart the Gateway.
- Validate config with `make doctor` (or the config validation endpoint) to catch YAML structure errors.
- If config is managed via API, re-fetch it and confirm models is a non-empty list.
- For tests, inject an AppConfig stub with at least one model instead of relying on global config.
Example fix
# config.yaml
# before
models: []
# after
models:
- name: gpt-4o
provider: openai
api_key: ${OPENAI_API_KEY} Defensive patterns
Strategy: validation
Validate before calling
from deerflow.config import get_app_config cfg = get_app_config() assert cfg.models, 'config.yaml has no models configured — agent creation will fail'
Type guard
def has_model(cfg) -> bool:
return bool(getattr(cfg, 'models', None)) and all(getattr(m, 'name', None) for m in cfg.models) Try / catch
try:
agent = create_agent(...)
except ValueError as e:
if 'No chat models are configured' in str(e):
raise SystemExit('Fix config.yaml: add at least one model entry') from e
raise Prevention
- Run `make doctor` after config changes.
- Fail startup early: validate models non-empty at Gateway boot, not at first run.
- Add a config schema test in CI that loads the example config and asserts models is non-empty.
When it happens
Trigger: Any agent/run creation when config.yaml (or the resolved AppConfig) contains no models: empty models list, failed config load falling through to defaults, or a config override wiping the list.
Common situations: Fresh clone where config.yaml was copied from example but models section left empty; CI/test environment without model config; typo in YAML indentation making models parse as a scalar; config API PATCH that replaced models with [].
Related errors
- No chat model could be resolved. Please configure at least…
- agent_storage.backend='db' requires database.backend to be…
- Failed to load configuration during gateway startup
- GATEWAY_WORKERS= cannot enable agentic browser tools…
- GATEWAY_WORKERS= cannot run with scheduler.enabled=true…
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/14123b5f4a6cda87.
Report an issue: GitHub.
Appendix: source
Thrown at backend/packages/harness/deerflow/agents/lead_agent/agent.py:133
tools.append(memory_tool)
existing_names.add(memory_tool.name)
def _get_runtime_config(config: RunnableConfig) -> dict:
"""Merge legacy configurable options with LangGraph runtime context."""
cfg = dict(config.get("configurable", {}) or {})
context = config.get("context", {}) or {}
if isinstance(context, dict):
cfg.update(context)
return cfg
def _resolve_model_name(requested_model_name: str | None = None, *, app_config: AppConfig | None = None) -> str:
"""Resolve a runtime model name safely, falling back to default if invalid. Returns None if no models are configured."""
app_config = app_config or get_app_config()
default_model_name = app_config.models[0].name if app_config.models else None
if default_model_name is None:
raise ValueError("No chat models are configured. Please configure at least one model in config.yaml.")
if requested_model_name and app_config.get_model_config(requested_model_name):
return requested_model_name
if requested_model_name and requested_model_name != default_model_name:
logger.warning(f"Model '{requested_model_name}' not found in config; fallback to default model '{default_model_name}'.")
return default_model_name
def _authorize_model_name(
model_name: str,
*,
context: Mapping[str, Any],
app_config: AppConfig,
) -> str:
"""Enforce ``model:use`` authorization on the resolved model name.
When ``authorization.enabled`` is false this is a no-op (returnsView on GitHub (pinned to 1dd6ba1acb)