HKUDS/Vibe-Trading · error · ValueError
schedule must be a non-empty string
Error message
schedule must be a non-empty string
What it means
validate_schedule accepts only a non-empty string — either a millisecond interval or a 5-field cron expression. Passing None, an empty string, whitespace-only input, or a non-string type (int, dict) fails this first shape check before any parsing is attempted.
Source
Thrown at agent/src/scheduled_research/models.py:126
Returns:
``True`` for a bare positive-integer interval, ``False`` otherwise
(including malformed input, which the validators reject separately).
"""
return bool(_INTERVAL_MS_RE.fullmatch(str(schedule).strip()))
def validate_schedule(schedule: str) -> None:
"""Raise ``ValueError`` when *schedule* is malformed.
Args:
schedule: Either a positive integer string (interval-ms) or a
simplified 5-field cron expression.
Raises:
ValueError: When the schedule does not match either accepted form.
"""
if not schedule or not isinstance(schedule, str):
raise ValueError("schedule must be a non-empty string")
if _INTERVAL_MS_RE.fullmatch(schedule.strip()):
# 15 digits ≈ 31,000 years in milliseconds — anything longer is not a
# usable interval and would only feed int() conversion of huge strings.
if len(schedule.strip()) > 15:
raise ValueError("interval is too large; expected at most 15 digits of milliseconds")
return # valid interval
parts = schedule.strip().split()
if len(parts) != _CRON_PARTS:
raise ValueError(f"schedule must be a positive integer (ms) or a 5-field cron string; got: {schedule!r}")
for part, (low, high) in zip(parts, CRON_BOUNDS):
_validate_cron_field(part, low, high)
def validate_timezone_shape(tz: Optional[str]) -> None:
"""Raise ``ValueError`` when *tz* is not ``None`` or a non-empty string.
View on GitHub (pinned to 80ffdda44c)
Solutions
- Ensure schedule is a non-empty string before calling, e.g. '3600000' or '0 9 * * 1-5'.
- Convert numeric intervals to strings: str(int(timedelta(minutes=30).total_seconds()*1000)).
- Default missing config fields to a concrete schedule rather than forwarding None.
Example fix
# before create_scheduled_run(schedule=None, ...) # after create_scheduled_run(schedule='0 9 * * 1-5', ...)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(schedule, str) or not schedule.strip():
schedule = '0 9 * * 1-5' # sane default
create_scheduled_run(schedule=schedule, ...) Type guard
def is_schedule_str(s) -> bool:
return isinstance(s, str) and bool(s.strip()) Try / catch
try:
create_scheduled_run(schedule=schedule, ...)
except ValueError as e:
if 'non-empty string' in str(e):
return bad_request('schedule is required')
raise Prevention
- Omit or null the field rather than sending ''.
- Convert numeric intervals to str(ms) before calling.
When it happens
Trigger: create_scheduled_run(schedule=None), schedule='' , schedule=3600000 (int instead of '3600000'), or an unset JSON field deserialized to None and forwarded directly.
Common situations: API payloads where the schedule field is omitted and defaults to None; YAML/JSON configs with a blank schedule key; passing a timedelta object that was never converted to ms.
Related errors
- cron field {part!r} is out of range; expected {low}-{high}
- cron field {part!r} is not valid; each field must be *, */n,
- cron range {atom!r} is reversed; expected low-high
- cron field {atom!r} is out of range; expected {low}-{high}
- interval is too large; expected at most 15 digits of millise
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/96f367fdee4fc551.
Report an issue: GitHub.