decolua/9router · info

[Claude Usage] OAuth endpoint returned ${oauthResponse.statu

Error message

[Claude Usage] OAuth endpoint returned ${oauthResponse.status}, falling back to legacy

What it means

fetchClaudeUsageRaw first calls Anthropic's OAuth usage endpoint; on any non-ok status (except the handled 429 cooldown path) it logs this warning and transparently falls back to the legacy settings + org usage endpoint. The value returned to the caller comes from the legacy path, so usage data is usually still available.

Source

Thrown at open-sse/services/usage/claude.js:126

          const modelName = key.replace("seven_day_", "");
          quotas[`weekly ${modelName} (7d)`] = createQuotaObject(value);
        }
      }

      return {
        plan: "Claude Code",
        extraUsage: data.extra_usage ?? null,
        quotas,
      };
    }

    // Cool down OAuth usage polling after a 429 (quota endpoint only)
    if (oauthResponse.status === 429) {
      oauthCooldown.set(accessToken, Date.now() + OAUTH_429_COOLDOWN_MS);
    }

    // Fallback: legacy settings + org usage endpoint
    console.warn(`[Claude Usage] OAuth endpoint returned ${oauthResponse.status}, falling back to legacy`);
    return await getClaudeUsageLegacy(accessToken, proxyOptions);
  } catch (error) {
    return { message: `Claude connected. Unable to fetch usage: ${error.message}` };
  }
}

/**
 * Legacy Claude usage for API key / org admin users
 */
async function getClaudeUsageLegacy(accessToken, proxyOptions = null) {
  try {
    const settingsResponse = await proxyAwareFetch(CLAUDE_CONFIG.settingsUrl, {
      method: "GET",
      headers: {
        "Authorization": `Bearer ${accessToken}`,
        "anthropic-version": CLAUDE_CONFIG.apiVersion,
      },
    }, proxyOptions);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. No action needed if the legacy fallback returns data — this is a downgrade warning only
  2. If fallback also fails, re-authenticate the Claude OAuth connection to get a fresh token
  3. Confirm the connected account's plan supports the OAuth usage endpoint
  4. Check Anthropic status/incidents if the status is 5xx
  5. Verify proxy settings aren't altering the usage request

Example fix

// before: stale token keeps hitting the new endpoint with 401
// after: re-run OAuth to refresh credentials, or shorten refresh interval
await refreshToken(connectionId); // before next fetchClaudeUsageRaw call
Defensive patterns

Strategy: fallback

Validate before calling

const conn = await api.get(`/api/connections/${id}`);
if (!conn || conn.tokenExpiresAt < Date.now()) await reauth(id); // refresh before usage fetch

Type guard

const hasUsageData = (u) => u && !u.message && typeof u === 'object';
if (!hasUsageData(usage)) console.warn('usage unavailable:', usage?.message);

Try / catch

try {
  const usage = await fetchClaudeUsageRaw(token);
  // legacy fallback already applied internally; validate shape
  if (usage?.message) console.warn(usage.message);
  return usage;
} catch (e) {
  console.warn(`claude usage unavailable: ${e.message}`);
  return null;
}

Prevention

When it happens

Trigger: The OAuth usage endpoint returned 400/401/403/404/5xx — expired OAuth token, account not eligible for the new usage API, region/plan without the endpoint, or transient upstream 5xx.

Common situations: OAuth access token expired or revoked (401); account on a plan that lacks the OAuth usage endpoint (404); Anthropic API change moved/renamed the endpoint; transient 500/503 during Anthropic incidents.

Related errors


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