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

  1. Use a real calendar date; check leap years for Feb 29 (2024 yes, 2025 no)
  2. Compute dates with date libraries (Python datetime/dateutil, JS date-fns) instead of string arithmetic
  3. Validate client-side with a regex plus calendar check (e.g. new Date(s) round-trip) before sending
  4. 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

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


AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15). Data as JSON: /api/errors/3658789e2110e06c. Report an issue: GitHub.