{"record":{"id":"4ba28be178f496f1","repo":"sansan0/TrendRadar","slug":"join-future-dates-today","errorCode":null,"errorMessage":"不允许查询未来日期: {', '.join(future_dates)}（当前日期: {today.strftime('%Y-%m-%d')}）","messagePattern":"不允许查询未来日期: (.+?)（当前日期: (.+?)）","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"mcp_server/utils/validators.py","lineNumber":474,"sourceCode":"        try:\n            from ..services.data_service import DataService\n            data_service = DataService()\n            earliest, latest = data_service.get_available_date_range()\n\n            if earliest and latest:\n                available_range = f\"{earliest.strftime('%Y-%m-%d')} 至 {latest.strftime('%Y-%m-%d')}\"\n            else:\n                available_range = \"无可用数据\"\n        except Exception:\n            available_range = \"未知（请检查 output 目录）\"\n\n        future_dates = []\n        if start_date.date() > today:\n            future_dates.append(start_str)\n        if end_date.date() > today and end_str != start_str:\n            future_dates.append(end_str)\n\n        raise InvalidParameterError(\n            f\"不允许查询未来日期: {', '.join(future_dates)}（当前日期: {today.strftime('%Y-%m-%d')}）\",\n            suggestion=f\"当前可用数据范围: {available_range}\"\n        )\n\n    return (start_date, end_date)\n\n\ndef validate_keyword(keyword: str) -> str:\n    \"\"\"\n    验证关键词\n\n    Args:\n        keyword: 搜索关键词\n\n    Returns:\n        处理后的关键词\n\n    Raises:","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/sansan0/TrendRadar/blob/8ee26026ba6c11dec41a95fb3895a7162876caa1/mcp_server/utils/validators.py#L456-L492","documentation":"Raised when start or end is strictly after today (server-local date). The message lists the future date(s) and today's date; the suggestion attempts to show the actual available data range by consulting DataService.get_available_date_range() (falling back to '未知（请检查 output 目录）' on failure). This guards both against typos and against querying dates with no data.","triggerScenarios":"Sending {\"start\": \"2030-01-01\", \"end\": \"2030-12-31\"}; a typo year like 2205-10-11; client clock skew if the client machine is ahead of the server; year-first transposition 2025→2052. start == today and end == today are fine; only strictly-future dates trip it.","commonSituations":"Forecast/planning queries against a historical-data-only service; LLM hallucinating future years; client/server timezone mismatch around midnight UTC vs local; typo'd years.","solutions":["Clamp both bounds to today client-side before sending","Fix year typos (2030/2205 style errors are almost always typos)","If client/server timezones differ, use the server's date notion (or clamp with margin) — 'today' is server-local datetime.now()","Read the suggestion's available range and query within it"],"exampleFix":"// before\n{\"date_range\": {\"start\": \"2025-10-01\", \"end\": \"2030-10-11\"}}\n// after\nconst today = new Date().toISOString().slice(0, 10);\n{\"date_range\": {\"start\": \"2025-10-01\", \"end\": today}}","handlingStrategy":"validation","validationCode":"const today = new Date().toISOString().slice(0, 10);\nif (dr.end > today) dr.end = today;\nif (dr.start > today) dr.start = today;\nif (dr.start > dr.end) dr.start = dr.end;","typeGuard":"const isNotFuture = (s: string): boolean => s <= new Date().toISOString().slice(0, 10);","tryCatchPattern":"try { call({ date_range: dr }); }\ncatch (e) {\n  const m = e.message.match(/当前日期: (\\d{4}-\\d{2}-\\d{2})/);\n  if (m) { dr.end = m[1]; if (dr.start > m[1]) dr.start = m[1]; call({ date_range: dr }); }\n  else throw e;\n}","preventionTips":["Clamp both bounds to today before every call","Use the server's reported date from a failed attempt to re-sync client clock assumptions","Watch timezone skew: server 'today' is server-local, not UTC"],"tags":["date-range","future-date","validation","clock"],"backgroundTag":null,"analyzedSha":"8ee26026ba6c11dec41a95fb3895a7162876caa1","analyzedAt":"2026-08-15T01:42:18.084Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}