sansan0/TrendRadar · error · ValueError
day_plan '{plan_key}' 中时间段 '{ranges[i][0]}' ({ranges[i][1]}-
Error message
day_plan '{plan_key}' 中时间段 '{ranges[i][0]}' ({ranges[i][1]}-{ranges[i][2]}) 与 '{ranges[j][0]}' ({ranges[j][1]}-{ranges[j][2]}) 存在重叠。请调整时间段,或将 overlap.policy 设为 'last_wins' What it means
Duplicate coverage of scheduler.py:390's message — same raise site, same meaning as error 78's underlying check but reached via the runtime path: _find_active_period found multiple candidate periods containing the current HH:MM and overlap.policy is 'error_on_overlap'. The scheduler lists the conflicting period names and times and tells the user how to opt into 'last_wins'.
Source
Thrown at trendradar/core/scheduler.py:390
period_keys = plan.get("periods", [])
if len(period_keys) <= 1:
continue
# 收集每个时间段的范围
ranges = []
for pk in period_keys:
p = periods.get(pk, {})
if "start" in p and "end" in p:
ranges.append((pk, p["start"], p["end"]))
# 两两检查重叠
for i in range(len(ranges)):
for j in range(i + 1, len(ranges)):
if self._ranges_overlap(
ranges[i][1], ranges[i][2],
ranges[j][1], ranges[j][2],
):
raise ValueError(
f"day_plan '{plan_key}' 中时间段 '{ranges[i][0]}' "
f"({ranges[i][1]}-{ranges[i][2]}) 与 '{ranges[j][0]}' "
f"({ranges[j][1]}-{ranges[j][2]}) 存在重叠。"
f"请调整时间段,或将 overlap.policy 设为 'last_wins'"
)
@staticmethod
def _ranges_overlap(s1: str, e1: str, s2: str, e2: str) -> bool:
"""检查两个时间范围是否重叠(支持跨日)"""
def to_minutes(t: str) -> int:
h, m = t.split(":")
return int(h) * 60 + int(m)
def expand_range(start: str, end: str) -> List[tuple]:
"""将时间范围展开为分钟段列表,跨日时拆分为两段"""
s = to_minutes(start)
e = to_minutes(end)
if s <= e:View on GitHub (pinned to 8ee26026ba)
Solutions
- Fix the period boundaries so they do not overlap.
- Set overlap: {policy: last_wins} to let the last-listed period win (warning logged, no error).
- If building timelines programmatically, run _validate_timeline before entering the scheduling loop.
Example fix
# before
periods:
a: {start: "08:00", end: "12:00"}
b: {start: "11:00", end: "13:00"}
# after
periods:
a: {start: "08:00", end: "11:00"}
b: {start: "11:00", end: "13:00"}
# or: overlap: {policy: last_wins} Defensive patterns
Strategy: validation
Validate before calling
# reuse the pairwise overlap lint from startup validation before resolve()
for plan in timeline["day_plans"].values():
keys = plan.get("periods", [])
for i in range(len(keys)):
for j in range(i + 1, len(keys)):
if ranges_overlap(timeline["periods"][keys[i]], timeline["periods"][keys[j]]):
raise ValueError(f"periods {keys[i]}/{keys[j]} overlap")
cfg = scheduler.resolve() Try / catch
try:
cfg = scheduler.resolve()
except ValueError as e:
if "时间段重叠冲突" in str(e):
# deterministic config bug: fix periods or set overlap.policy=last_wins
raise SystemExit(f"schedule config error: {e}")
raise Prevention
- Always validate timelines (startup validator) before the scheduling loop; the runtime check is a backstop, not the primary guard.
- Avoid mutating timeline data after scheduler construction.
When it happens
Trigger: resolve() called at a time of day inside two periods of the active day plan (e.g. 11:30 with 08:00-12:00 and 11:00-13:00 both active); default policy. Note the startup validator (_check_period_overlaps) normally catches this earlier, so reaching the runtime raise means validation was skipped or the timeline mutated afterwards.
Common situations: Dynamically built or patched timelines that bypass _validate_timeline; periods added at runtime by orchestration code; cross-midnight spans overlapping early-morning periods.
Related errors
- week_map 缺少星期映射: {weekday}
- week_map[{weekday}] 引用了不存在的 day_plan: {day_plan_key}
- 检测到时间段重叠冲突: {', '.join(conflicting)} 在 {now_hhmm} 重叠。请调整时间段配
- period '{period_key}' 的 start 与 end 不能相同: {period['start']}
- 不支持的传输模式: {transport}
AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15).
Data as JSON: /api/errors/21c085144f4ad016.
Report an issue: GitHub.