datawhalechina/hello-agents · warning · ValueError
议题不能为空
Error message
议题不能为空
What it means
run_historical_debate (the generator in debate_orchestrator.py) strips its topic argument and raises ValueError('议题不能为空') when the result is empty. This is deliberate input validation at the top of the debate pipeline: an empty topic would send meaningless prompts through four LLM phases (round1, digest, round2, synthesis), so the orchestrator refuses before creating an LLM client or emitting any events.
Source
Thrown at Co-creation-projects/meiguanxiHXX-historyReviewAgent/historical_review/debate_orchestrator.py:110
llm_model: str | None = None,
llm_max_tokens: int | None = 4096,
llm_timeout: int | None = None,
) -> Iterator[dict[str, Any]]:
"""
逐步产出辩论过程事件,供 SSE / 日志展示。
事件类型
--------
- progress: step, total, message
- round1_start / round1_end: role, content(end)
- digest_start / digest_end: content(end)
- round2_start / round2_end: role, content(end)
- synthesis_start / synthesis_end: content(end)
- complete: markdown(全文)
"""
topic = (topic or "").strip()
if not topic:
raise ValueError("议题不能为空")
if llm is None:
llm = create_llm(
api_key=llm_api_key,
base_url=llm_base_url,
model=llm_model,
max_tokens=llm_max_tokens,
timeout=llm_timeout,
temperature=0.4,
)
step = 0
yield _yield_progress(step, f"议题已接收:{topic[:80]}{'…' if len(topic) > 80 else ''}")
step += 1
evidence_block = ""
if use_evidence_bundle:View on GitHub (pinned to 606a07d341)
Solutions
- Pass a non-empty topic: run_historical_debate("评价唐朝灭亡的原因") after stripping whitespace yourself.
- If calling from the web layer, validate/strip req.topic in the endpoint (app.py already does this and returns HTTP 400) rather than letting the orchestrator raise.
- In CLIs, argparse with required=True plus a check that topic.strip() is non-empty prevents silent empty strings.
- Catch ValueError at the caller boundary and surface it as a user-facing '请输入议题' message instead of a stack trace.
Example fix
# before
run_historical_debate(topic=user_input)
# after
topic = (user_input or "").strip()
if not topic:
raise SystemExit("请输入有效的议题")
run_historical_debate(topic=topic) Defensive patterns
Strategy: validation
Validate before calling
topic = (topic or "").strip()
if not topic:
raise ValueError("议题不能为空 — provide a non-empty debate topic")
md = run_historical_debate(topic, ...) Type guard
def is_valid_topic(topic: object) -> bool:
return isinstance(topic, str) and bool(topic.strip()) Try / catch
try:
md = collect_debate(run_historical_debate(topic, ...))
except ValueError as e:
if "议题不能为空" in str(e):
# user-input problem — re-prompt, never retry the same input
raise UserInputError(str(e)) from e
raise Prevention
- Strip and validate topic at every entry point (CLI, web, API)
- Validate in Pydantic models so HTTP callers get clean 400s
- Never retry an input-validation error with the same payload
When it happens
Trigger: Calling run_historical_debate(""), run_historical_debate(None), or a topic of only whitespace/newlines; a UI passing an unvalidated textarea value straight through; a CLI arg like --topic '' ; upstream code trimming the topic to empty before forwarding it.
Common situations: Frontend form submitted with an empty topic field; programmatic callers forwarding user input without validation; trimming logic that reduces a punctuation-only topic to an empty string; API clients testing the endpoint with empty payloads.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/a161b3af8ffb5e79.
Report an issue: GitHub.