{"record":{"id":"7fcd21d96a9cae2d","repo":"unclecode/crawl4ai","slug":"invalid-window-window-only-5m-is-currently-s","errorCode":null,"errorMessage":"Invalid window: {window}. Only '5m' is currently supported","messagePattern":"Invalid window: (.+?)\\. Only '5m' is currently supported","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"deploy/docker/monitor_routes.py","lineNumber":111,"sourceCode":"        return monitor.get_endpoint_stats_summary()\n    except Exception as e:\n        logger.error(f\"Error getting endpoint stats: {e}\")\n        raise HTTPException(500, str(e))\n\n\n@router.get(\"/timeline\")\nasync def get_timeline(metric: str = \"memory\", window: str = \"5m\"):\n    \"\"\"Get timeline data for charts.\n\n    Args:\n        metric: 'memory', 'requests', or 'browsers'\n        window: Time window (only '5m' supported for now)\n    \"\"\"\n    # Input validation\n    if metric not in [\"memory\", \"requests\", \"browsers\"]:\n        raise HTTPException(400, f\"Invalid metric: {metric}. Must be one of: memory, requests, browsers\")\n    if window != \"5m\":\n        raise HTTPException(400, f\"Invalid window: {window}. Only '5m' is currently supported\")\n\n    try:\n        monitor = get_monitor()\n        return monitor.get_timeline_data(metric, window)\n    except Exception as e:\n        logger.error(f\"Error getting timeline: {e}\")\n        raise HTTPException(500, str(e))\n\n\n@router.get(\"/logs/janitor\")\nasync def get_janitor_log(limit: int = 100):\n    \"\"\"Get recent janitor cleanup events.\"\"\"\n    # Input validation\n    if limit < 1 or limit > 1000:\n        raise HTTPException(400, f\"Invalid limit: {limit}. Must be between 1 and 1000\")\n\n    try:\n        monitor = get_monitor()","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/monitor_routes.py#L93-L129","documentation":"An explicit 400 validation error raised by GET /monitor/timeline when the window query parameter is not exactly '5m'. The timeline feature currently implements only a single fixed 5-minute window, so the check is a strict equality gate (window != '5m') rather than a parsed duration - any other value, including longer/shorter windows, is rejected.","triggerScenarios":"Calling GET /monitor/timeline?window=1m, ?window=15m, ?window=300s, or omitting a custom default when constructing the URL manually; dashboards that send a user-selected time range other than 5 minutes.","commonSituations":"UI time-range selector offers multiple windows but the backend only supports one; API consumers assuming ISO-8601 durations or second-based values; default value differs between client (e.g. '1h') and server ('5m').","solutions":["Send exactly window=5m (the default) - it is the only supported value.","Pin the client's time-range selector to a single 'Last 5 minutes' option until the server supports more windows.","To support other windows, extend monitor.get_timeline_data() to accept parsed durations, then relax the equality check to an allow-list."],"exampleFix":"# before\nconst url = `/monitor/timeline?metric=memory&window=${range}`; // range = '1h'\n\n# after\nconst url = `/monitor/timeline?metric=memory&window=5m`;","handlingStrategy":"validation","validationCode":"def valid_window(w: str) -> bool:\n    return w == '5m'\n\nwindow = w if valid_window(w) else '5m'\nurl = f\"/monitor/timeline?window={window}\"","typeGuard":"from typing import Literal\n\nWindow = Literal['5m']\n\ndef is_window(v: str) -> TypeGuard[Window]:\n    return v == '5m'","tryCatchPattern":"try:\n    resp = get(f\"{base}/monitor/timeline?window={window}\")\nexcept HTTPError as e:\n    if e.response.status_code == 400:\n        window = '5m'  # only supported value; retry once with it\n        resp = get(f\"{base}/monitor/timeline?window=5m\")\n    else:\n        raise","preventionTips":["Until the server supports more windows, hard-code window=5m (or omit it - it is the default).","Do not expose a time-range selector that implies other windows are accepted.","When adding windows server-side, update this check and the client selector in the same change."],"tags":["fastapi","monitoring","validation","query-params"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}