sansan0/TrendRadar · error · InvalidParameterError
开始日期不能晚于结束日期
Error message
开始日期不能晚于结束日期
What it means
Raised by normalize_date_range when both dates parse successfully but start_date > end_date — an inverted range. The suggestion echoes the offending pair. Note equality is allowed (single-day range), only strictly-later starts are rejected.
Source
Thrown at mcp_server/utils/validators.py:447
raise InvalidParameterError(
"date_range 必须是字典类型、日期字符串或有效的JSON字符串",
suggestion='例如: {"start": "2025-10-01", "end": "2025-10-11"} 或 "2025-10-01"'
)
start_str = date_range.get("start")
end_str = date_range.get("end")
if not start_str or not end_str:
raise InvalidParameterError(
"date_range 必须包含 start 和 end 字段",
suggestion='例如: {"start": "2025-10-01", "end": "2025-10-11"}'
)
start_date = validate_date(start_str)
end_date = validate_date(end_str)
if start_date > end_date:
raise InvalidParameterError(
"开始日期不能晚于结束日期",
suggestion=f"start: {start_str}, end: {end_str}"
)
# 检查日期是否在未来
today = datetime.now().date()
if start_date.date() > today or end_date.date() > today:
# 获取可用日期范围提示
try:
from ..services.data_service import DataService
data_service = DataService()
earliest, latest = data_service.get_available_date_range()
if earliest and latest:
available_range = f"{earliest.strftime('%Y-%m-%d')} 至 {latest.strftime('%Y-%m-%d')}"
else:
available_range = "无可用数据"
except Exception:View on GitHub (pinned to 8ee26026ba)
Solutions
- Swap the values so start <= end
- Compute end first, then start = end - timedelta(days=N), never the reverse unguarded
- Add a client-side assert: if (start > end) [start, end] = [end, start]
- Remember single-day queries can use start == end or the bare date string
Example fix
# before
{"date_range": {"start": "2025-10-11", "end": "2025-10-01"}}
# after
{"date_range": {"start": "2025-10-01", "end": "2025-10-11"}}
# defensive swap
start, end = min(start, end), max(start, end) Defensive patterns
Strategy: validation
Validate before calling
let [start, end] = [dr.start, dr.end]; if (new Date(start) > new Date(end)) [start, end] = [end, start]; // or reject in UI
Type guard
const isOrderedRange = (s: string, e: string): boolean => s <= e; // ISO strings compare lexicographically
Try / catch
try { call({ date_range: dr }); }
catch (e) {
if (/开始日期不能晚于结束日期/.test(e.message)) call({ date_range: { start: dr.end, end: dr.start } });
else throw e;
} Prevention
- ISO YYYY-MM-DD strings sort lexicographically — compare before sending
- Derive start from end (end - N days) rather than independent computations
- Date-picker UIs: enforce start<=end at input time
When it happens
Trigger: Sending {"start": "2025-10-11", "end": "2025-10-01"}; swapping the keys; auto-generated ranges where the bound computation inverted (e.g. subtracting from the wrong end); timezone-crossing logic that produces off-by-one inversions near midnight.
Common situations: UI date pickers returning fields in display order (mm-dd) mapped to start/end wrongly; LLMs writing later date first; code computing start = today, end = today - N days by accident.
Related errors
- 日期表达式不能为空
- date_range JSON 解析失败: {e}
- 无法识别的日期表达式: {stripped}
- date_range 必须包含 start 和 end 字段
- 不允许查询未来日期: {', '.join(future_dates)}(当前日期: {today.strftime('
AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15).
Data as JSON: /api/errors/ca1b98ab89589bc8.
Report an issue: GitHub.