sansan0/TrendRadar · error · InvalidParameterError
日期格式错误: {stripped}
Error message
日期格式错误: {stripped} What it means
Raised by normalize_date_range when the input is a 10-character string with dashes at positions 4 and 7 (shaped like YYYY-MM-DD) but strptime rejects it — i.e. syntactically date-shaped but not a real calendar date. Examples: 2025-13-01 (month 13), 2025-02-30, 2025-00-10, 2025-10-32.
Source
Thrown at mcp_server/utils/validators.py:402
if isinstance(date_range, str):
stripped = date_range.strip()
# 1. 检查是否是 JSON 对象格式
if stripped.startswith('{') and stripped.endswith('}'):
try:
date_range = json.loads(stripped)
except json.JSONDecodeError as e:
raise InvalidParameterError(
f"date_range JSON 解析失败: {e}",
suggestion='请使用正确的JSON格式: {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"}'
)
# 2. 检查是否是单日字符串格式 YYYY-MM-DD
elif len(stripped) == 10 and stripped[4] == '-' and stripped[7] == '-':
try:
single_date = datetime.strptime(stripped, "%Y-%m-%d")
return (single_date, single_date)
except ValueError:
raise InvalidParameterError(
f"日期格式错误: {stripped}",
suggestion="请使用 YYYY-MM-DD 格式,例如: 2025-10-11"
)
# 3. 尝试自然语言解析
else:
try:
result = DateParser.resolve_date_range_expression(stripped)
if result.get("success"):
dr = result["date_range"]
start_date = datetime.strptime(dr["start"], "%Y-%m-%d")
end_date = datetime.strptime(dr["end"], "%Y-%m-%d")
return (start_date, end_date)
else:
raise InvalidParameterError(
f"无法识别的日期表达式: {stripped}",
suggestion="支持格式: YYYY-MM-DD, {\"start\": \"...\", \"end\": \"...\"}, 或自然语言(今天、本周、最近7天等)"
)
except InvalidParameterError:View on GitHub (pinned to 8ee26026ba)
Solutions
- Use a real calendar date; check leap years for Feb 29 (2024 yes, 2025 no)
- Compute dates with date libraries (Python datetime/dateutil, JS date-fns) instead of string arithmetic
- Validate client-side with a regex plus calendar check (e.g. new Date(s) round-trip) before sending
- If you need a range, send the {"start", "end"} object rather than a single-day string
Example fix
// before
{"date_range": "2025-02-30"}
// after
{"date_range": "2025-02-28"} Defensive patterns
Strategy: validation
Validate before calling
function isRealDate(s: string): boolean {
if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return false;
const [y, m, d] = s.split('-').map(Number);
const dt = new Date(Date.UTC(y, m - 1, d));
return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;
}
if (!isRealDate(dateRange)) throw new Error('invalid calendar date'); Type guard
const isCalendarDate = (s: string): boolean => {
const [y, m, d] = s.split('-').map(Number);
const dt = new Date(Date.UTC(y, m - 1, d));
return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;
}; Try / catch
try { call({ date_range: s }); }
catch (e) {
if (/日期格式错误/.test(e.message)) call({ date_range: iso(new Date(s)) });
else throw e;
} Prevention
- Generate dates with datetime/date-fns, never string math
- Round-trip check: new Date(s) must reproduce the same y/m/d
- Beware Feb 29 on non-leap years in LLM-computed dates
When it happens
Trigger: Passing date_range: "2025-02-30" (Feb 30), "2025-13-01" (month 13), or "abcd-ef-gh" (10 chars, dashes in place, non-numeric). The pre-check only inspects length and dash positions, so content errors surface here via strptime ValueError.
Common situations: LLM arithmetic on dates producing impossible days (Feb 29 on non-leap years like 2025-02-29); month/day transposition creating month>12; hand-typed dates; template strings with placeholder junk.
Related errors
- INVALID_PARAMETER
- 不能查询未来的日期: {date.strftime('%Y-%m-%d')}
- 日期太久远: {date.strftime('%Y-%m-%d')} ({days_ago}天前)
- 日期表达式不能为空
- 日期格式错误: {date_str}
AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15).
Data as JSON: /api/errors/3658789e2110e06c.
Report an issue: GitHub.