decolua/9router · error · Error

Failed to reset Codex limit

Error message

Failed to reset Codex limit

What it means

handleResetCodexLimit POSTs to /api/usage/<connectionId>/codex-reset-credits to spend one of the connection's reset credits against the Codex rate-limit window. On non-OK responses it throws result.message || result.error || result.code || 'Failed to reset Codex limit'. Notable non-OK outcomes include 409 code:no_credit (no credits left), 400 (not a Codex/OAuth connection), 401 (credential refresh failed), and 5xx upstream errors.

Source

Thrown at src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.js:317

      await fetchQuota(connectionId, provider, { force: true });
      setLastUpdated(new Date());
    },
    [fetchQuota],
  );

  const handleResetCodexLimit = useCallback(
    async (connectionId, provider) => {
      if (provider !== "codex" || resettingLimitId) return;

      setResettingLimitId(connectionId);
      setErrors((prev) => ({ ...prev, [connectionId]: null }));

      try {
        const response = await fetch(`/api/usage/${connectionId}/codex-reset-credits`, { method: "POST" });
        const result = await response.json().catch(() => ({}));

        if (!response.ok) {
          throw new Error(result.message || result.error || result.code || "Failed to reset Codex limit");
        }

        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(() => ({}));

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. If the message/code is no_credit (HTTP 409), wait for the credit to replenish or the rate-limit window to reset — there is nothing to redeem.
  2. Confirm the connection is a Codex connection with authType oauth or access_token; plain API-key connections cannot redeem credits.
  3. If you see 'Credential refresh failed', re-authorize the Codex connection to obtain a fresh refresh token.
  4. Check upstream status / retry if the code is unknown_response (502), as the consume result was unparseable.

Example fix

// before
throw new Error(result.message || result.error || result.code || "Failed to reset Codex limit");
// after
if (result.code === "no_credit") throw new Error("No Codex reset credits available — wait for replenishment");
throw new Error(result.message || result.error || result.code || `Failed to reset Codex limit (HTTP ${response.status})`);
Defensive patterns

Strategy: validation

Validate before calling

if (connection.provider !== "codex") throw new Error("Reset credits only apply to Codex connections");
if (!["oauth", "access_token"].includes(connection.authType)) throw new Error("Codex reset credits require an OAuth or access-token connection");
const info = await fetch(`/api/usage/${connection.id}/codex-reset-credits`).then((r) => r.json()).catch(() => ({}));
if (Array.isArray(info.credits) && info.credits.length === 0) throw new Error("No reset credits available");

Type guard

const isConsumeResult = (r) => r && typeof r === "object" && typeof r.code === "string" && typeof r.reset === "boolean";

Try / catch

try {
  const res = await fetch(`/api/usage/${connectionId}/codex-reset-credits`, { method: "POST" });
  const result = await res.json().catch(() => ({}));
  if (!res.ok) {
    if (result.code === "no_credit") throw new Error("No Codex reset credits available");
    throw new Error(result.message || result.error || result.code || `Reset failed (HTTP ${res.status})`);
  }
} catch (error) {
  setErrors((prev) => ({ ...prev, [connectionId]: error.message }));
}

Prevention

When it happens

Trigger: POST /api/usage/<id>/codex-reset-credits returns non-OK: 409 { code:'no_credit' } when no reset credits remain; 400 when the connection's provider is not codex or authType is neither oauth nor access_token; 401 'Credential refresh failed'; 502 when the upstream consume call returns an unexpected response.

Common situations: User clicks 'reset' after all credits were consumed (409 no_credit); connection re-authenticated as plain API key instead of OAuth; Codex OAuth refresh token expired; upstream OpenAI/Codex outage.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/632fdb9ed6cc0e23. Report an issue: GitHub.