can1357/oh-my-pi · error · AIError.ProviderHttpError
Invalid Copilot usage response
Error message
Invalid Copilot usage response
What it means
Thrown when GitHub's /copilot_internal/user endpoint returns HTTP 200 but the JSON body is not a plain object, so it cannot be shaped into CopilotUsageResponse. The library validates the envelope (isRecord) before casting and refuses to continue with an unusable payload. The 200 status passed to ProviderHttpError signals the failure was payload-shaped, not transport-level.
Source
Thrown at packages/ai/src/usage/github-copilot.ts:187
} catch {
return undefined;
}
}
async function fetchInternalUsage(
ctx: UsageFetchContext,
githubApiBaseUrl: string,
token: string,
signal?: AbortSignal,
): Promise<CopilotUsageResponse> {
const headers: Record<string, string> = {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${token}`,
...OPENCODE_HEADERS,
};
const data = await fetchJson(ctx, `${githubApiBaseUrl}/copilot_internal/user`, { headers, signal });
if (!isRecord(data)) throw new AIError.ProviderHttpError("Invalid Copilot usage response", 200);
return data as CopilotUsageResponse;
}
async function fetchBillingUsage(
ctx: UsageFetchContext,
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",View on GitHub (pinned to 9690622007)
Solutions
- Log or capture the actual response body to see what replaced the expected JSON object.
- Verify the GitHub API base URL points at api.github.com (or a transparent JSON proxy), not an HTML-serving gateway.
- Re-authenticate behind SSO/proxies — complete any pending device or browser login flow.
- Update the library if GitHub changed the internal endpoint shape; check for a newer version.
Example fix
// before: custom proxy base URL that serves HTML on 200 baseUrl = "https://gateway.corp.internal/github"; // after: use the real GitHub API endpoint baseUrl = "https://api.github.com";
Defensive patterns
Strategy: type-guard
Type guard
function isRecord(v: unknown): v is Record<string, unknown> {
return typeof v === "object" && v !== null && !Array.isArray(v);
}
// pre-validate the same shape the library checks
const data: unknown = await res.json();
if (!isRecord(data)) throw new Error("Copilot usage endpoint returned non-object JSON"); Try / catch
try {
const usage = await copilot.usage(params);
} catch (err) {
if (err instanceof AIError.ProviderHttpError && err.message === "Invalid Copilot usage response") {
logger.warn("Copilot usage: non-JSON/proxied 200 response — check network path");
} else throw err;
} Prevention
- Ensure no proxy/gateway injects HTML (login pages) into api.github.com responses.
- Test from the deployment network — captive portals often return 200 HTML.
- Pin/verify the library version against the current copilot_internal response shape.
When it happens
Trigger: fetchInternalUsage receives a 200 response whose parsed JSON is null, an array, a string, or a number instead of an object — typically when an auth proxy, login page, or HTML error interstitial is served instead of the real JSON, or GitHub changes the internal endpoint's response shape.
Common situations: Corporate SSO proxy returning an HTML redirect/login page with status 200; captive portal Wi-Fi; hitting a mirror/base URL that is not the real GitHub API; GitHub changing the undocumented copilot_internal response contract.
Related errors
- Invalid Copilot billing 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/4be5fbc1f3618423.
Report an issue: GitHub.