{"record":{"id":"3ae8f22054ee005e","repo":"Significant-Gravitas/AutoGPT","slug":"str-exc","errorCode":null,"errorMessage":"str(exc)","messagePattern":"str\\(exc\\)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"autogpt_platform/backend/backend/api/features/admin/block_cost_admin_routes.py","lineNumber":83,"sourceCode":"    if start.tzinfo is None:\n        start = start.replace(tzinfo=timezone.utc)\n    if end.tzinfo is None:\n        end = end.replace(tzinfo=timezone.utc)\n\n    logger.info(\n        \"Admin %s aggregating block cost estimates [%s..%s] min_samples=%s\",\n        admin_user_id,\n        start.isoformat(),\n        end.isoformat(),\n        min_samples,\n    )\n\n    try:\n        rows = await compute_block_cost_estimates(\n            start=start, end=end, min_samples=min_samples\n        )\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc)) from exc\n\n    # Ceil so a [00:00:00Z, 23:59:59.999Z] window — what the frontend sends for\n    # an inclusive 7-day pick — reports 7, not 6 (`.days` would truncate).\n    window_days = math.ceil((end - start).total_seconds() / 86400)\n\n    return BlockCostEstimatesResponse(\n        estimates=rows,\n        total_rows=len(rows),\n        window_days=window_days,\n        max_window_days=ANALYTICS_MAX_DAYS,\n        min_samples=min_samples,\n        generated_at=datetime.now(timezone.utc),\n    )\n","sourceCodeStart":65,"sourceCodeEnd":97,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/admin/block_cost_admin_routes.py#L65-L97","documentation":"HTTP 400 raised when compute_block_cost_estimates raises ValueError. The dominant causes are a window longer than ANALYTICS_MAX_DAYS or start > end. The ValueError's message is forwarded verbatim as the detail, so the response body tells you which constraint failed.","triggerScenarios":"Sending start/end spanning more than ANALYTICS_MAX_DAYS days (e.g. a quarter-long window against a 30/90-day cap), or an inverted range (start after end). The naive-to-UTC coercion above means tz-naive values are accepted, so timezone shape is not the trigger.","commonSituations":"Admin analytics UI defaulting to a 90-day window when the cap is smaller; picking a custom range that crosses the cap; DST or manual typing producing end < start.","solutions":["Read the detail field — it names the exact violated constraint.","Narrow the window to ANALYTICS_MAX_DAYS or fewer days (compare against max_window_days in any successful response).","Swap start/end if inverted.","For long histories, page through consecutive windows under the cap."],"exampleFix":"// before\nconst days = 180; // exceeds ANALYTICS_MAX_DAYS\n\n// after\nconst MAX = lastResponse.max_window_days; // honor the advertised cap\nconst days = Math.min(requestedDays, MAX);","handlingStrategy":"validation","validationCode":"const maxDays = 30; // read max_window_days from a prior response when possible\nconst days = Math.min(maxDays, (end - start) / 86400000);\nif (days < 0) throw new Error('start must be <= end');","typeGuard":null,"tryCatchPattern":"try { const r = await adminBlockCostEstimates({ start, end }); } catch (e) { if (e.status === 400) { /* read e.detail: names the exact cap; narrow the window and retry once */ } }","preventionTips":["Cache max_window_days from responses and clamp the picker's selectable span to it.","Always validate start <= end client-side.","Split long analyses into consecutive capped windows."],"tags":["http-400","admin-api","analytics","time-window"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}