decolua/9router · error · Error
Failed to load Codex reset credits
Error message
Failed to load Codex reset credits
What it means
handleViewCodexResetCredits GETs /api/usage/<connectionId>/codex-reset-credits (cache: no-store) to list the connection's available reset credits and throws result.error || result.message || 'Failed to load Codex reset credits' on non-OK. The route 404s for unknown connections, 400s for non-Codex or non-OAuth/access-token connections, 401s when the OAuth credential refresh fails, and 500s when the upstream credits lookup throws.
Source
Thrown at src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.js:337
await fetchQuota(connectionId, provider);
setLastUpdated(new Date());
} catch (error) {
setErrors((prev) => ({ ...prev, [connectionId]: error.message || "Failed to reset Codex limit" }));
} finally {
setResettingLimitId(null);
}
},
[fetchQuota, resettingLimitId],
);
const handleViewCodexResetCredits = useCallback(async (connection) => {
setResetCreditsState({ connection, loading: true, error: null, data: null });
try {
const response = await fetch(`/api/usage/${connection.id}/codex-reset-credits`, { cache: "no-store" });
const result = await response.json().catch(() => ({}));
if (!response.ok) {
throw new Error(result.error || result.message || "Failed to load Codex reset credits");
}
const credits = Array.isArray(result.credits) ? [...result.credits] : [];
credits.sort((a, b) => {
const aTime = a.expiresAt ? new Date(a.expiresAt).getTime() : Number.POSITIVE_INFINITY;
const bTime = b.expiresAt ? new Date(b.expiresAt).getTime() : Number.POSITIVE_INFINITY;
return aTime - bTime;
});
setResetCreditsState({ connection, loading: false, error: null, data: { ...result, credits } });
} catch (error) {
setResetCreditsState({ connection, loading: false, error: error.message || "Failed to load Codex reset credits", data: null });
}
}, []);
const handleDeleteConnection = useCallback(
async (id) => {
if (!confirm("Delete this connection?")) return;
setDeletingId(id);
try {View on GitHub (pinned to 90b52e06ff)
Solutions
- Verify the connection still exists — reload the connections list (a 404 means it was deleted).
- Confirm the connection is provider=codex with authType oauth or access_token; otherwise the endpoint intentionally returns 400.
- On 'Credential refresh failed', re-authorize the Codex OAuth connection in the dashboard.
- Retry after checking network/proxy settings if the 500 stems from the upstream credits lookup.
Example fix
// before
throw new Error(result.error || result.message || "Failed to load Codex reset credits");
// after
throw new Error(result.error || result.message || `Failed to load Codex reset credits (HTTP ${response.status})`); Defensive patterns
Strategy: validation
Validate before calling
if (!connection || connection.provider !== "codex") { setResetCreditsState({ connection: null, loading: false, error: "Not a Codex connection", data: null }); return; }
if (!["oauth", "access_token"].includes(connection.authType)) { setResetCreditsState({ connection: null, loading: false, error: "OAuth or access-token connection required", data: null }); return; } Type guard
const isCreditsPayload = (r) => r && typeof r === "object" && (r.credits === undefined || Array.isArray(r.credits));
Try / catch
try {
const response = await fetch(`/api/usage/${connection.id}/codex-reset-credits`, { cache: "no-store" });
const result = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(result.error || result.message || `Failed to load credits (HTTP ${response.status})`);
setResetCreditsState({ connection, loading: false, error: null, data: result.credits || [] });
} catch (e) {
setResetCreditsState({ connection, loading: false, error: e.message, data: null });
} Prevention
- Only open the credits modal for live, codex, oauth/access-token connections.
- Handle 404 by refreshing the connections list (stale row after deletion).
- Re-authorize the connection when credential-refresh failures occur.
When it happens
Trigger: GET /api/usage/<id>/codex-reset-credits returns non-OK while opening the reset-credits modal: 404 'Connection not found', 400 'Codex reset credits are only available for Codex connections' / 'require an OAuth or access-token connection', 401 'Credential refresh failed: ...', or 500 from the upstream getCodexRateLimitResetCredits call.
Common situations: Opening the modal for a stale/deleted connection; connection authenticated via API key only; Codex OAuth token expired and refresh token invalid; network/proxy failure reaching the Codex usage endpoint.
Related errors
- Failed to reset Codex limit
- HTTP ${response.status}: ${errorMsg}
- `ClinePass token exchange failed: ${error}`
- `CodeBuddy state request failed: ${await response.text()}`
- `CodeBuddy Intl state request failed: ${await response.text(
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/12e4bcb884fda298.
Report an issue: GitHub.