HKUDS/Vibe-Trading · error · ValueError
source.prompt is required
Error message
source.prompt is required
What it means
When draft.source.kind is 'prompt' (the default), source.prompt must be a non-empty string after stripping. This is the instruction the scheduler will run periodically.
Source
Thrown at agent/src/scheduled_research/service.py:138
now = int(time.time() * 1000) if now_ms is None else now_ms
title = str(draft.get("title") or "").strip()
if not title:
raise ValueError("title is required")
source = draft.get("source")
schedule_spec = draft.get("schedule")
delivery_spec = draft.get("delivery") or {"mode": "in_app"}
if not isinstance(source, Mapping) or not isinstance(schedule_spec, Mapping):
raise ValueError("source and schedule must be objects")
if not isinstance(delivery_spec, Mapping):
raise ValueError("delivery must be an object")
source_type = str(source.get("kind") or "prompt")
playbook_slug = None
config: dict[str, Any] = {}
if source_type == "prompt":
prompt = str(source.get("prompt") or "").strip()
if not prompt:
raise ValueError("source.prompt is required")
elif source_type == "playbook":
playbook_slug = str(source.get("playbook_slug") or "").strip()
if not playbook_slug:
raise ValueError("source.playbook_slug is required")
playbook = get_playbook(playbook_slug)
variables = source.get("variables") or {}
if not isinstance(variables, Mapping):
raise ValueError("source.variables must be an object")
prompt = playbook.render(variables)
config["playbook"] = playbook_slug
else:
raise ValueError("source.kind must be 'prompt' or 'playbook'")
expression = str(schedule_spec.get("expression") or "").strip()
timezone = schedule_spec.get("timezone")
validate_schedule(expression)
if is_interval_schedule(expression):
validate_timezone_shape(timezone)View on GitHub (pinned to 80ffdda44c)
Solutions
- Set source.prompt to the research instruction text
- If you meant a playbook, set kind='playbook' and playbook_slug instead
- Require the prompt field in client validation when kind is prompt
Example fix
// before
{"source": {"kind": "prompt"}}
// after
{"source": {"kind": "prompt", "prompt": "Summarize AI news"}} Defensive patterns
Strategy: validation
Validate before calling
src = draft.get("source", {})
if str(src.get("kind") or "prompt") == "prompt":
assert str(src.get("prompt") or "").strip(), "source.prompt is required" Type guard
def prompt_source_valid(src: dict) -> bool:
return str(src.get("kind") or "prompt") != "prompt" or bool(str(src.get("prompt") or "").strip()) Try / catch
try:
propose_create(draft)
except ValueError as e:
require_prompt_field() if "source.prompt" in str(e) else raise_ Prevention
- Require prompt text in the creation form when kind is prompt
- Default missing prompts to a meaningful template rather than empty
When it happens
Trigger: source={"kind":"prompt"} with prompt omitted, empty, or whitespace; kind defaulted to 'prompt' because it was absent while prompt was also absent.
Common situations: Minimal drafts that only set schedule; UI where the prompt textarea is optional; templates with an empty prompt slot.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- title is required
- source.playbook_slug is required
- delivery.target_ref is required for configured delivery
- title is required
- thesis is required
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/a9ef8b9e7eca8fd7.
Report an issue: GitHub.