{"record":{"id":"a23d02489ce99a8a","repo":"bytedance/deer-flow","slug":"no-chat-model-could-be-resolved-please-configure","errorCode":null,"errorMessage":"No chat model could be resolved. Please configure at least one model in config.yaml or provide a valid 'model_name'/'model' in the request.","messagePattern":"No chat model could be resolved\\. Please configure at least one model in config\\.yaml or provide a valid 'model_name'/'model' in the request\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"backend/packages/harness/deerflow/agents/lead_agent/agent.py","lineNumber":747,"sourceCode":"    thinking_enabled = bool(_resolve_runtime_option(cfg, \"thinking_enabled\", agent_thinking, True))\n    reasoning_effort = _resolve_runtime_option(cfg, \"reasoning_effort\", agent_reasoning, None)\n\n    # Per-agent sampling overrides (temperature / max_tokens) layered on top of\n    # the resolved model profile (issue #4336). None when the agent set none.\n    agent_model_settings = getattr(agent_config, \"model_settings\", None) if agent_config else None\n    agent_model_overrides = agent_model_settings.model_dump(exclude_none=True) if agent_model_settings else None\n\n    # Final model name resolution: request → agent config → global default, with fallback for unknown names\n    model_name = _resolve_model_name(requested_model_name or agent_model_name, app_config=resolved_app_config)\n\n    # Phase 3: enforce model:use authorization. On deny, fall back to the first\n    # allowed model (graceful) rather than crashing the run (RFC §9).\n    model_name = _authorize_model_name(model_name, context=cfg, app_config=resolved_app_config)\n\n    model_config = resolved_app_config.get_model_config(model_name)\n\n    if model_config is None:\n        raise ValueError(\"No chat model could be resolved. Please configure at least one model in config.yaml or provide a valid 'model_name'/'model' in the request.\")\n    if thinking_enabled and not model_config.supports_thinking:\n        logger.warning(f\"Thinking mode is enabled but model '{model_name}' does not support it; fallback to non-thinking mode.\")\n        thinking_enabled = False\n\n    logger.info(\n        \"Create Agent(%s) -> thinking_enabled: %s, reasoning_effort: %s, model_name: %s, is_plan_mode: %s, subagent_enabled: %s, max_concurrent_subagents: %s, max_total_subagents: %s\",\n        agent_name or \"default\",\n        thinking_enabled,\n        reasoning_effort,\n        model_name,\n        is_plan_mode,\n        subagent_enabled,\n        max_concurrent_subagents,\n        max_total_subagents,\n    )\n\n    # Inject run metadata for LangSmith trace tagging\n    if \"metadata\" not in config:","sourceCodeStart":729,"sourceCodeEnd":765,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/lead_agent/agent.py#L729-L765","documentation":"ValueError at the end of agent creation: after name resolution and authorization fallback, app_config.get_model_config(model_name) still returned None. This means the resolved/authorized model name is not in the config's model list — possible when authorization fell back to a name that exists in the policy but not in config.yaml, or config changed between resolution and lookup.","triggerScenarios":"authz fallback returns a candidate model name that the RBAC policy allows but config.yaml does not define; or a race where the AppConfig is swapped mid-run (hot config reload) so get_model_config misses.","commonSituations":"RBAC policy lists models that were never added to config.yaml (policy/config drift); config reloaded with a trimmed models list while old policy still references removed names; default model deleted from config after the policy was written.","solutions":["Align the RBAC/authz model allowlist with config.yaml models: every policy-visible model must have a config entry.","Ensure config.yaml defines at least one model (see error 465) and that the default model exists.","Pass an explicit valid model_name/'model' in the request context.","After any config.yaml change, restart the Gateway so resolution and lookups see one consistent AppConfig."],"exampleFix":"# policy allows: [\"llama-3\"] but config.yaml lacks it\n# before (config.yaml)\nmodels:\n  - name: gpt-4o\n\n# after\nmodels:\n  - name: gpt-4o\n  - name: llama-3\n    provider: ollama","handlingStrategy":"validation","validationCode":"cfg = get_app_config()\nallowed_by_policy = set(provider.filter_resources(principal, 'model', [m.name for m in cfg.models]))\nusable = [m.name for m in cfg.models if m.name in allowed_by_policy]\nassert usable, 'policy and config.yaml disagree: no model is both configured and authorized'","typeGuard":null,"tryCatchPattern":"try:\n    agent = create_agent(...)\nexcept ValueError as e:\n    if 'No chat model could be resolved' in str(e):\n        # check policy/config drift: re-sync authz allowlist with config.yaml models, then retry\n        sync_policy_with_config_models(); agent = create_agent(...)\n    raise","preventionTips":["Keep RBAC model lists and config.yaml models generated from one source of truth.","Add a startup check: intersection of policy-allowed and configured models is non-empty.","Restart Gateway after config model changes to avoid partial-reload races."],"tags":["config","authz","model","drift","valueerror"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}