datawhalechina/hello-agents · error · HTTPException

{str(exc)}

Error message

{str(exc)}

What it means

HTTPException(400) raised by POST /research in the chapter14 deep-research backend when _build_config(payload) or the agent raises ValueError — the route deliberately maps ValueError to a client-error 400 with the original message. It marks configuration the request asked for as unsupported (bad model name, bad provider, invalid search settings) rather than a server fault.

Source

Thrown at code/chapter14/helloagents-deepresearch/backend/src/main.py:125

            config.max_web_research_loops,
            config.fetch_full_page,
            config.use_tool_calling,
            config.strip_thinking_tokens,
            _mask_secret(config.llm_api_key),
        )

    @app.get("/healthz")
    def health_check() -> Dict[str, str]:
        return {"status": "ok"}

    @app.post("/research", response_model=ResearchResponse)
    def run_research(payload: ResearchRequest) -> ResearchResponse:
        try:
            config = _build_config(payload)
            agent = DeepResearchAgent(config=config)
            result = agent.run(payload.topic)
        except ValueError as exc:  # Likely due to unsupported configuration
            raise HTTPException(status_code=400, detail=str(exc)) from exc
        except Exception as exc:  # pragma: no cover - defensive guardrail
            raise HTTPException(status_code=500, detail="Research failed") from exc

        todo_payload = [
            {
                "id": item.id,
                "title": item.title,
                "intent": item.intent,
                "query": item.query,
                "status": item.status,
                "summary": item.summary,
                "sources_summary": item.sources_summary,
                "note_id": item.note_id,
                "note_path": item.note_path,
            }
            for item in result.todo_items
        ]

View on GitHub (pinned to 606a07d341)

Solutions

  1. Read the detail field — it is the original ValueError text naming the unsupported value
  2. Fix the request payload (correct model/provider names, valid numeric fields) per the ResearchRequest schema
  3. If the value should be supported, extend _build_config's allowlist rather than catching the 400

Example fix

# before
payload = {"topic": "quantum computing", "model": "gpt-99"}  # -> 400

# after
payload = {"topic": "quantum computing", "model": "deepseek-chat"}  # a supported id
r = requests.post(f'{BASE}/research', json=payload)
if r.status_code == 400:
    print('Bad request config:', r.json()['detail'])
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_MODELS = {'deepseek-chat', 'deepseek-reasoner', ...}  # mirror _build_config

def valid_research_payload(p: dict) -> bool:
    return (
        bool(str(p.get('topic', '')).strip())
        and p.get('model', 'default') in SUPPORTED_MODELS
    )

Type guard

def is_supported_model(m) -> bool:
    return isinstance(m, str) and m in SUPPORTED_MODELS

Try / catch

r = requests.post(f'{BASE}/research', json=payload)
if r.status_code == 400:
    raise ValueError(f'Unsupported research config: {r.json()["detail"]}')  # actionable message
r.raise_for_status()

Prevention

When it happens

Trigger: Payload specifying an unknown/unsupported model or provider; malformed enum-ish fields (e.g. invalid search depth or max iterations as strings) that _build_config parses and rejects; empty/whitespace topic triggering validation ValueError.

Common situations: Frontend sending a model id removed after a backend update; user-typed config fields passed straight through; API consumers guessing field values instead of following the schema.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/63b60bbed7f7a061. Report an issue: GitHub.