can1357/oh-my-pi · error · AIError.ProviderHttpError
Invalid Copilot billing usage response
Error message
Invalid Copilot billing usage response
What it means
Thrown by fetchBillingUsage when the GitHub Copilot billing usage endpoint returns 200 but the body is not a JSON object, so it cannot be treated as BillingUsageResponse. Like the internal-user variant, the library checks isRecord(data) and throws ProviderHttpError with status 200 to indicate a malformed payload rather than an HTTP failure.
Source
Thrown at packages/ai/src/usage/github-copilot.ts:211
baseUrl: string,
username: string,
token: string,
signal?: AbortSignal,
): Promise<BillingUsageResponse> {
const data = await fetchJson(
ctx,
`${baseUrl}/users/${encodeURIComponent(username)}/settings/billing/premium_request/usage`,
{
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
signal,
},
);
if (!isRecord(data)) throw new AIError.ProviderHttpError("Invalid Copilot billing usage response", 200);
return data as BillingUsageResponse;
}
function buildLimitFromQuota(
key: string,
label: string,
quota: CopilotQuotaDetail,
plan: string,
window: UsageWindow | undefined,
accountId?: string,
): UsageLimit {
const used = quota.unlimited ? undefined : Math.max(0, quota.entitlement - quota.remaining);
const limit = quota.unlimited ? undefined : quota.entitlement;
const amount = buildAmount(used, limit, "requests");
const notes: string[] = [];
if (quota.unlimited) notes.push("Unlimited");
if (quota.overage_count > 0) {
notes.push(`Overage requests: ${quota.overage_count}`);View on GitHub (pinned to 9690622007)
Solutions
- Inspect the raw 200 body to identify what the endpoint actually returned.
- Confirm the base URL matches GitHub's billing API for the account type (github.com vs GHE with matching endpoint).
- Bypass or correctly configure proxies that could inject HTML responses.
- Upgrade the library if GitHub altered the billing usage response schema.
Example fix
// before: pointing billing fetch at GHE host lacking this endpoint const data = await fetchBillingUsage(ctx, "https://ghe.corp.example/api", ...); // after: use the public GitHub billing API const data = await fetchBillingUsage(ctx, "https://api.github.com", ...);
Defensive patterns
Strategy: type-guard
Type guard
function isBillingUsage(v: unknown): v is Record<string, unknown> {
return typeof v === "object" && v !== null && !Array.isArray(v) && "quota_snapshots" in v;
} Try / catch
try {
const billing = await provider.billing(params);
} catch (err) {
if (err instanceof AIError.ProviderHttpError && /Invalid Copilot billing usage response/.test(err.message)) {
// capture raw body upstream / fall back to cached report
} else throw err;
} Prevention
- Use the correct billing API base for the account type (github.com vs enterprise).
- Bypass HTML-injecting proxies for API hosts (allowlist api.github.com).
- Watch GitHub changelogs for billing endpoint schema changes and update the library.
When it happens
Trigger: A successful (200) response from the billing usage endpoint whose parsed JSON is not an object — HTML from a proxy, an array, null, or a changed API response schema.
Common situations: Enterprise proxy or API gateway serving an interstitial page; GHE (GitHub Enterprise) base URL whose billing endpoint differs from github.com's; upstream API contract change on the billing endpoint.
Related errors
- Invalid Copilot usage response
- Auth broker response failed schema validation
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE must contain a JSON object
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for ${provider} must
- Kilo device authorization response missing required fields
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3ff78051ed940561.
Report an issue: GitHub.