{"record":{"id":"b87c7a5c86a9c7de","repo":"Significant-Gravitas/AutoGPT","slug":"rate-limit-reset-is-not-available","errorCode":null,"errorMessage":"Rate limit reset is not available.","messagePattern":"Rate limit reset is not available\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/chat/routes.py","lineNumber":1028,"sourceCode":"        },\n        503: {\n            \"description\": \"Service Unavailable (Redis reset failed; credits refunded or support needed)\"\n        },\n    },\n)\nasync def reset_copilot_usage(\n    user_id: Annotated[str, Security(auth.get_user_id)],\n) -> RateLimitResetResponse:\n    \"\"\"Reset the daily CoPilot rate limit by spending credits.\n\n    Allows users who have hit their daily cost limit to spend credits\n    to reset their daily usage counter and continue working.\n    Returns 400 if the feature is disabled or the user is not over the limit.\n    Returns 402 if the user has insufficient credits.\n    \"\"\"\n    cost = config.rate_limit_reset_cost\n    if cost <= 0:\n        raise HTTPException(\n            status_code=400,\n            detail=\"Rate limit reset is not available.\",\n        )\n\n    if not settings.config.enable_credit:\n        raise HTTPException(\n            status_code=400,\n            detail=\"Rate limit reset is not available (credit system is disabled).\",\n        )\n\n    daily_limit, weekly_limit, tier = await get_global_rate_limits(\n        user_id,\n        config.daily_cost_limit_microdollars,\n        config.weekly_cost_limit_microdollars,\n    )\n\n    if daily_limit <= 0:\n        raise HTTPException(","sourceCodeStart":1010,"sourceCodeEnd":1046,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/chat/routes.py#L1010-L1046","documentation":"HTTP 400 from POST /usage/reset (reset_copilot_usage in backend/api/features/chat/routes.py:1028). The endpoint lets a user spend credits to reset their daily CoPilot cost limit, but the very first guard rejects the call when the server-side config value `rate_limit_reset_cost` is <= 0. The field lives in backend/copilot/config.py:375 where the docstring states '0 = disabled', so this is an intentionally disabled feature, not a transient fault.","triggerScenarios":"Calling the rate-limit-reset endpoint on a deployment where COPILOT_RATE_LIMIT_RESET_COST (or the config default) is set to 0. In tests, mocker.patch.object(chat_routes.config, \"rate_limit_reset_cost\", 0) reproduces it exactly (routes_test.py:2587).","commonSituations":"Fresh local dev environment where the flag was zeroed to disable paid resets; production rollback that disabled the feature but the frontend still shows the 'reset for credits' button; misreading the config unit (credits/cents) and setting 0 intentionally.","solutions":["Set rate_limit_reset_cost to a positive value (default 500 cents/credits) in backend/copilot/config.py or via the corresponding env var, then restart the backend.","If the feature is intentionally disabled, hide the reset button in the client (check the usage-status payload, which exposes rate_limit_reset_cost=0) instead of calling the endpoint.","If you are the client developer, treat HTTP 400 with this detail as a permanent 'feature off' signal and stop retrying."],"exampleFix":"# before (config disabled but endpoint still called)\nawait post('/chat/usage/reset')  # -> 400 \"Rate limit reset is not available.\"\n\n# after: enable in backend config\n# backend/backend/copilot/config.py\nrate_limit_reset_cost: int = Field(default=500, ge=0)\n\n# or client-side: consult usage status first\nif (usage.rate_limit_reset_cost > 0) await post('/chat/usage/reset')","handlingStrategy":"validation","validationCode":"// before calling the reset endpoint, confirm the feature is priced\nconst usage = await getUsageStatus();\nif (usage.rate_limit_reset_cost <= 0) {\n  showNotice('Paid reset is disabled on this deployment');\n} else {\n  await post('/chat/usage/reset');\n}","typeGuard":null,"tryCatchPattern":"try { await post('/chat/usage/reset'); } catch (e) { if (e.status === 400 && /not available/.test(e.detail)) { hideResetUI(); return; } throw e; }","preventionTips":["Gate the reset button on rate_limit_reset_cost > 0 from the usage-status payload","Treat 400 'not available' as permanent config — never auto-retry","Keep deployment config in sync: if credits are off, zero the reset cost too"],"tags":["http","config","rate-limit","credits","fastapi"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}