datawhalechina/hello-agents · warning · HTTPException
缺少必需字段: llm
Error message
缺少必需字段: llm
What it means
Raised by PUT /config/CONFIG when the parsed object has no 'llm' key. config.json is required to carry an 'llm' section because the agent reads model settings from it; a structurally valid object without that key is rejected with HTTP 400 before the write, so the on-disk file is never left half-configured.
Source
Thrown at Co-creation-projects/tino-chen-HelloClaw/src/api/config.py:101
@router.put("/{name}")
async def update_config(name: str, request: ConfigUpdateRequest, ws: WorkspaceManager = Depends(get_workspace)):
"""更新配置文件"""
# 特殊处理 CONFIG (config.json)
if name == "CONFIG":
ensure_config_json_exists()
# 严格校验 JSON 格式
try:
config_data = json.loads(request.content)
except json.JSONDecodeError as e:
raise HTTPException(status_code=400, detail=f"无效的 JSON 格式: {str(e)}")
# 校验必需字段
if not isinstance(config_data, dict):
raise HTTPException(status_code=400, detail="配置必须是 JSON 对象")
if "llm" not in config_data:
raise HTTPException(status_code=400, detail="缺少必需字段: llm")
llm_config = config_data.get("llm", {})
required_fields = ["model_id", "api_key", "base_url"]
missing_fields = [f for f in required_fields if f not in llm_config]
if missing_fields:
raise HTTPException(status_code=400, detail=f"llm 配置缺少必需字段: {', '.join(missing_fields)}")
config_path = get_config_json_path()
with open(config_path, "w", encoding="utf-8") as f:
f.write(request.content)
return {"name": name, "status": "updated"}
# 处理 .md 配置文件
if name not in ws.list_configs():
raise HTTPException(status_code=404, detail=f"配置文件 {name} 不存在")
ws.save_config(name, request.content)
return {"name": name, "status": "updated"}View on GitHub (pinned to 606a07d341)
Solutions
- Add an "llm" object as a top-level key: {"llm": {...}}
- Check for exact lowercase spelling 'llm' — the check is case-sensitive
- Start from GET /config/CONFIG output and edit values rather than building the file from scratch
Example fix
// before
content = JSON.stringify({model: {model_id: "gpt-4"}})
// after
content = JSON.stringify({llm: {model_id: "gpt-4", api_key: "sk-...", base_url: "https://api.openai.com/v1"}}) Defensive patterns
Strategy: validation
Validate before calling
const parsed = JSON.parse(content);
if (!('llm' in parsed)) showError('Missing required top-level key: llm'); Type guard
const hasLlm = (v: Record<string, unknown>): v is Record<string, unknown> & { llm: unknown } =>
'llm' in v; Prevention
- Treat GET /config/CONFIG output as the schema template
- Remember the key check is case-sensitive: exactly 'llm'
When it happens
Trigger: PUT /api/config/CONFIG with content like {"model": {...}} (key named differently), {"LLM": {...}} (wrong case), or {} (empty object).
Common situations: Renaming the key to match a newer config schema; user trimmed the file down to unrelated settings; frontend builds the object from optional form fields and omits llm entirely when its sub-form is untouched.
Related errors
- 无效的 JSON 格式: {str(e)}
- 配置必须是 JSON 对象
- llm 配置缺少必需字段: {', '.join(missing_fields)}
- user_id 无效
- movie_id 必须为正整数
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/13e8e6a611f5c0c9.
Report an issue: GitHub.