decolua/9router · error · Error

Failed to consume Codex reset credit: ${error.message}

Error message

Failed to consume Codex reset credit: ${error.message}

What it means

This error wraps any failure that occurs while calling the Codex upstream endpoint to redeem a rate-limit reset credit. The library performs a proxied fetch that posts { redeem_request_id } and parses the response as JSON; any network error, proxy failure, or invalid-JSON body is caught and re-thrown with this prefix, discarding the original error type. It indicates the credit-consumption step of the rate-limit reset flow did not complete.

Source

Thrown at open-sse/services/usage/codex.js:205

  }

  let response;
  let data = null;
  try {
    response = await proxyAwareFetch(CODEX_CONFIG.resetCreditsConsumeUrl, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${accessToken}`,
        "Accept": "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ redeem_request_id: redeemRequestId }),
    }, proxyOptions);

    const text = await response.text();
    data = text ? JSON.parse(text) : null;
  } catch (error) {
    throw new Error(`Failed to consume Codex reset credit: ${error.message}`);
  }

  const code = data?.code || null;
  const windowsReset = toFiniteNumber(data?.windows_reset, 0);
  const success = response.ok && (code === "reset" || windowsReset > 0);

  return {
    ok: success,
    noCredit: response.ok && code === "no_credit",
    status: response.status,
    code,
    windowsReset,
    message: data?.message || null,
    raw: data,
  };
}

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Check network/proxy connectivity to the Codex endpoint from the machine running the gateway
  2. Log the underlying error.message (included in the thrown message) to identify whether it is fetch vs JSON.parse
  3. Retry with a fresh redeem_request_id — the old one may be expired or already consumed
  4. Verify proxyOptions (proxy URL/agent) are correct if a proxy is configured

Example fix

// before
const text = await response.text();
data = text ? JSON.parse(text) : null;
// after
const text = await response.text();
try {
  data = text ? JSON.parse(text) : null;
} catch (parseErr) {
  throw new Error(`Codex reset credit response not JSON (status ${response.status}): ${text.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof redeemRequestId !== "string" || !redeemRequestId) throw new Error("redeem_request_id required before consuming Codex reset credit");

Type guard

function hasRedeemId(v) { return typeof v === "string" && v.length > 0; }

Try / catch

try {
  await consumeCodexRateLimitResetCredit(args);
} catch (e) {
  if (/Failed to consume Codex reset credit/.test(e.message)) {
    logger.warn("codex reset credit failed", { cause: e.message });
    // schedule retry with a fresh redeem_request_id
  } else throw e;
}

Prevention

When it happens

Trigger: consumeCodexRateLimitResetCredit is invoked (via consumeResult or the POST handler) and: the upstream fetch throws (network/timeout/DNS), the proxy options are invalid, or response.text() returns non-JSON text that JSON.parse cannot parse. Redeem request ids for expired or already-consumed credits may also surface through here if the upstream responds unparseably.

Common situations: Corporate proxy misconfiguration, the Codex endpoint being unreachable or returning an HTML error page, expired/redeemed redeem_request_id causing a non-JSON error body, or transient network flaps during the reset call.

Related errors


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