mastra-ai/mastra · error
Invalid Copilot models response: missing `data` array
Error message
Invalid Copilot models response: missing `data` array
What it means
After a successful HTTP response, fetchCopilotModels parses the JSON and validates that it has a `data` array per the models API contract. If the body is missing, is not an object, or `data` is not an array, the library throws this contract-validation error rather than iterating over malformed data.
Source
Thrown at mastracode/sdk/src/auth/providers/github-copilot.ts:483
}): Promise<CopilotModelEntry[]> {
const url = `${opts.baseUrl.replace(/\/$/, '')}/models`;
const response = await fetch(url, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${opts.bearerToken}`,
...COPILOT_HEADERS,
},
signal: opts.signal,
});
if (!response.ok) {
const text = await response.text().catch(() => '');
throw new Error(`Failed to fetch Copilot models: ${response.status} ${response.statusText}: ${text}`);
}
const json = await response.json().catch(() => null);
if (!json || typeof json !== 'object' || !Array.isArray((json as { data?: unknown }).data)) {
throw new Error('Invalid Copilot models response: missing `data` array');
}
const data = (json as { data: unknown[] }).data;
const result: CopilotModelEntry[] = [];
for (const item of data) {
if (!item || typeof item !== 'object') continue;
const obj = item as Record<string, unknown>;
if (obj.model_picker_enabled !== true) continue;
const policy = obj.policy as Record<string, unknown> | undefined;
if (policy && policy.state === 'disabled') continue;
const id = obj.id;
if (typeof id !== 'string' || !id) continue;
const name = typeof obj.name === 'string' ? obj.name : id;View on GitHub (pinned to 75dd419e61)
Solutions
- Log/inspect the raw response body to see what was actually returned (proxy pages and error JSON are common culprits)
- Verify the request targets the official Copilot models endpoint, not a proxy or wrong base URL
- Bypass proxies/VPNs and retry to rule out interception
- If GitHub changed the API shape, update the SDK/provider version
Example fix
// before (proxy returns 200 + HTML) baseURL: 'http://proxy.internal/github' // after baseURL: 'https://api.individual.githubcopilot.com'
Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-flight probe: fetch and validate the shape yourself before trusting the provider
const res = await fetch(modelsUrl, { headers, signal });
const ct = res.headers.get('content-type') ?? '';
if (!ct.includes('application/json')) {
throw new Error(`Unexpected content-type from models endpoint: ${ct} (proxy interception?)`);
} Type guard
function hasDataArray(json: unknown): json is { data: unknown[] } {
return typeof json === 'object' && json !== null && Array.isArray((json as { data?: unknown }).data);
} Try / catch
try {
models = await provider.models();
} catch (err) {
if (err instanceof Error && err.message.includes('missing `data` array')) {
// 2xx but wrong shape: log body, check for proxy/captive-portal interference
console.error('Copilot models endpoint returned a non-contract payload; bypass proxy and retry.');
} else throw err;
} Prevention
- Ensure no proxy/captive portal can return 200 HTML pages for API hosts
- Pin/verify the correct Copilot models endpoint URL in configuration
- Log raw response bodies on contract errors to detect interception early
- Keep the SDK updated for Copilot API shape changes
When it happens
Trigger: The models endpoint returns 2xx with an unexpected body: an HTML login/proxy page, an error JSON without `data` (e.g. {message: ...} from a gateway), or an API version change that renamed/moved the `data` field.
Common situations: Corporate proxy or captive portal returning 200 with HTML; a reverse proxy intercepting the request; GitHub changing the Copilot models API shape; pointing the provider at a non-Copilot endpoint.
Related errors
- Failed to fetch Copilot models: ${response.status} ${respons
- Telegram ${method} failed: ${detail}
- Perplexity Search request failed with status ${response.stat
- ${response.status} ${response.statusText}: ${text}
- Invalid device code response
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/0b58843486ad9bf4.
Report an issue: GitHub.