QuantumNous/new-api · warning · Error

Failed to fetch usage

Error message

Failed to fetch usage

What it means

Thrown in the channels table's update-balance/usage action for channel type 57 (Codex) when getCodexUsage(channel.id) returns success:false, or as the catch-path fallback when a non-Error exception occurs. It aborts opening the Codex usage dialog and surfaces a toast.

Source

Thrown at web/src/features/channels/components/channels-columns.tsx:431

        </Tooltip>
      </TooltipProvider>
    )
  }

  // Regular channel row: show used and remaining with click to update
  const variant = getBalanceVariant(balance)

  const handleClickUpdate = async () => {
    if (isUpdating) {
      return
    }

    setIsUpdating(true)
    if (channel.type === 57) {
      try {
        const res = await getCodexUsage(channel.id)
        if (!res.success) {
          throw new Error(res.message || t('Failed to fetch usage'))
        }
        setCodexUsageResponse(res)
        setCodexUsageOpen(true)
      } catch (error) {
        toast.error(
          error instanceof Error ? error.message : t('Failed to fetch usage')
        )
      } finally {
        setIsUpdating(false)
      }
      return
    }

    await handleUpdateChannelBalance(channel.id, queryClient)
    setIsUpdating(false)
  }
  let remainingBadgeLabel = sensitiveVisible ? remainingDisplay : SENSITIVE_MASK
  if (sensitiveVisible && isUpdating) {

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Read the toast — res.message from the backend states the upstream reason (auth failure, quota endpoint error).
  2. Open the channel edit dialog and verify/re-enter the Codex credentials, then retest the channel.
  3. Confirm the channel is enabled and of the correct type/key format expected by the Codex usage endpoint.
  4. If upstream is down, retry later; usage fetching depends on the provider's availability.
Defensive patterns

Strategy: try-catch

Validate before calling

if (channel.type !== 57 || isUpdating) return // only Codex channels hit this path

Type guard

function isCodexUsageSuccess(res: unknown): res is { success: true; data: unknown } {
  return typeof res === 'object' && res !== null && (res as any).success === true
}

Try / catch

try {
  const res = await getCodexUsage(channel.id)
  if (!res.success) throw new Error(res.message || t('Failed to fetch usage'))
  setCodexUsageResponse(res)
  setCodexUsageOpen(true)
} catch (error) {
  toast.error(error instanceof Error ? error.message : t('Failed to fetch usage'))
} finally {
  setIsUpdating(false)
}

Prevention

When it happens

Trigger: Clicking the usage/update action on a channel row with channel.type === 57 invokes GET of the Codex usage endpoint; the backend returns success:false (channel credentials rejected upstream, channel disabled, or internal error).

Common situations: Codex channel's API key invalid or expired so usage lookup fails upstream; channel not yet tested/saved with valid credentials; upstream Codex API outage or rate limit; channel deleted by another admin between render and click.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/a79545b21c0bbbe8. Report an issue: GitHub.