{"record":{"id":"cb7898c81a6154cc","repo":"Significant-Gravitas/AutoGPT","slug":"str-exc-cb7898","errorCode":null,"errorMessage":"str(exc)","messagePattern":"str\\(exc\\)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"autogpt_platform/backend/backend/api/features/admin/credit_admin_routes.py","lineNumber":159,"sourceCode":"    logger.info(\n        \"Admin %s exporting credit transactions [%s..%s] type=%s user=%s incl_inactive=%s\",\n        admin_user_id,\n        start.isoformat(),\n        end.isoformat(),\n        transaction_type.value if transaction_type else None,\n        user_id,\n        include_inactive,\n    )\n    try:\n        history = await admin_export_user_history(\n            start=start,\n            end=end,\n            transaction_type=transaction_type,\n            user_id=user_id,\n            include_inactive=include_inactive,\n        )\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc)) from exc\n    return CreditTransactionsExportResponse(\n        transactions=history,\n        total_rows=len(history),\n        window_days=(end - start).days,\n        max_window_days=CREDIT_EXPORT_MAX_DAYS,\n    )\n\n\nclass CopilotUsageExportResponse(BaseModel):\n    rows: list[CopilotWeeklyUsageRow]\n    total_rows: int\n    window_days: int\n    max_window_days: int\n\n\n@router.get(\n    \"/copilot-usage/export\",\n    response_model=CopilotUsageExportResponse,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/admin/credit_admin_routes.py#L141-L177","documentation":"HTTP 400 from the credit-transaction export endpoint; admin_export_user_history raised ValueError and its message becomes the response detail. By design the export is capped at CREDIT_EXPORT_MAX_DAYS days and CREDIT_EXPORT_MAX_ROWS rows, and any violation (window too long, or a constraint on the filters) surfaces here as a 400 instead of silently truncated data.","triggerScenarios":"Requesting a window longer than CREDIT_EXPORT_MAX_DAYS; start after end; or an invalid combination of transaction_type/user_id filters that the data layer rejects.","commonSituations":"Finance wanting a full-quarter export when the cap is 90 days; admins paginating by widening the range instead of narrowing it; typo'd transaction_type value.","solutions":["Read the detail message to identify which cap was breached.","Split the export into consecutive windows of at most CREDIT_EXPORT_MAX_DAYS days (the response reports window_days and max_window_days).","Add user_id or transaction_type filters to keep row count under CREDIT_EXPORT_MAX_ROWS.","Verify start <= end."],"exampleFix":"# before: one 180-day request\ncurl '/admin/credits/export?start=2026-01-01T00:00:00Z&end=2026-06-30T00:00:00Z'\n\n# after: two capped windows\ncurl '/admin/credits/export?start=2026-01-01T00:00:00Z&end=2026-03-31T23:59:59Z'\ncurl '/admin/credits/export?start=2026-04-01T00:00:00Z&end=2026-06-30T23:59:59Z'","handlingStrategy":"validation","validationCode":"const MAX_DAYS = 90; // keep in sync with CREDIT_EXPORT_MAX_DAYS\nfunction splitWindows(start: Date, end: Date): [Date, Date][] { /* consecutive <=MAX_DAYS slices */ }","typeGuard":null,"tryCatchPattern":"try { await exportCredits({ start, end }); } catch (e) { if (e.status === 400 && /days/.test(e.detail)) { for (const [s, t] of splitWindows(start, end)) await exportCredits({ start: s, end: t }); } }","preventionTips":["Chunk exports into windows under the advertised cap before requesting.","Filter by transaction_type/user_id to stay under the row cap.","Read window_days/max_window_days from responses to self-calibrate."],"tags":["http-400","admin-api","credits","export","rate-limit"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}