sansan0/TrendRadar · error · ValueError
period '{period_key}' 缺少 start 或 end 字段
Error message
period '{period_key}' 缺少 start 或 end 字段 What it means
Raised by _validate_timeline when a period's start and end are identical. A zero-length period is rejected because the scheduler's range semantics (start inclusive, end exclusive) would make it never match, hiding a likely config mistake. Format validity of each field is checked separately just before this comparison.
Source
Thrown at trendradar/core/scheduler.py:348
# day_plan 引用完整性
for day, plan_key in timeline["week_map"].items():
if plan_key not in timeline["day_plans"]:
raise ValueError(
f"week_map[{day}] 引用了不存在的 day_plan: {plan_key}"
)
# period 引用完整性
for plan_key, plan in timeline["day_plans"].items():
for period_key in plan.get("periods", []):
if period_key not in timeline["periods"]:
raise ValueError(
f"day_plan[{plan_key}] 引用了不存在的 period: {period_key}"
)
# 时间格式校验
for period_key, period in timeline["periods"].items():
if "start" not in period or "end" not in period:
raise ValueError(
f"period '{period_key}' 缺少 start 或 end 字段"
)
self._validate_hhmm(period["start"], f"{period_key}.start")
self._validate_hhmm(period["end"], f"{period_key}.end")
if period["start"] == period["end"]:
raise ValueError(
f"period '{period_key}' 的 start 与 end 不能相同: {period['start']}"
)
# 检查冲突策略下的重叠
policy = timeline.get("overlap", {}).get("policy", "error_on_overlap")
if policy == "error_on_overlap":
self._check_period_overlaps(timeline)
def _check_period_overlaps(self, timeline: Dict[str, Any]) -> None:
"""
检查每个日计划中的时间段是否存在重叠
View on GitHub (pinned to 8ee26026ba)
Solutions
- Set end strictly after start (or before it for a cross-midnight span), e.g. "12:00"-"12:01" for a near-instant window.
- If you meant 'all day', use "00:00"-"23:59" or the default config instead.
- Double-check copy-pasted periods where end was meant to be edited.
Example fix
# before
periods:
ping: {start: "12:00", end: "12:00"}
# after
periods:
ping: {start: "12:00", end: "12:05"} Defensive patterns
Strategy: validation
Validate before calling
for key, p in timeline.get("periods", {}).items():
if p["start"] == p["end"]:
raise ValueError(f"period '{key}': start == end ({p['start']}); use a real span") Type guard
def is_nonzero_period(p: dict) -> bool:
return p.get("start") != p.get("end") Try / catch
try:
scheduler = Scheduler(schedule_config, timeline_data)
except ValueError as e:
if "start 与 end 不能相同" in str(e):
raise SystemExit(f"timeline config error: {e}")
raise Prevention
- Never use equal start/end; for a near-instant window use a 1-minute span.
- For all-day coverage use 00:00-23:59 or the default config.
When it happens
Trigger: periods: {noon: {start: "12:00", end: "12:00"}} — intended as a one-shot instant but encoded as equal boundaries; copy-paste where end was not updated after start.
Common situations: Attempting to schedule a single-moment trigger; placeholder values left in both fields; timezone shifts applied equally to both fields after copy-paste.
Related errors
- DATA_NOT_FOUND
- 不支持的传输模式: {transport}
- 未知的预设模板: '{preset}',可选值: {', '.join(presets.keys())}, custom
- 检测到时间段重叠冲突: {', '.join(conflicting)} 在 {now_hhmm} 重叠。请调整时间段配
- timeline 缺少必须字段: {key}
AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15).
Data as JSON: /api/errors/4eb7d58493db004f.
Report an issue: GitHub.