mastra-ai/mastra · error

Invalid Copilot token response fields

Error message

Invalid Copilot token response fields

What it means

After `refreshGitHubCopilotToken` confirms the Copilot token response is an object, it validates that `token` is a string and `expires_at` is a number (Unix seconds). Missing or mistyped fields mean the Copilot token endpoint returned ok but without the expected bearer-token payload, so the SDK refuses to build `GitHubCopilotCredentials`. This is defensive validation against API drift or partial responses.

Source

Thrown at mastracode/sdk/src/auth/providers/github-copilot.ts:357

      headers: {
        Accept: 'application/json',
        Authorization: `Bearer ${refreshToken}`,
        ...COPILOT_HEADERS,
      },
    },
    signal,
  );

  if (!raw || typeof raw !== 'object') {
    throw new Error('Invalid Copilot token response');
  }

  const obj = raw as Record<string, unknown>;
  const token = obj.token;
  const expiresAt = obj.expires_at;

  if (typeof token !== 'string' || typeof expiresAt !== 'number') {
    throw new Error('Invalid Copilot token response fields');
  }

  const credentials: GitHubCopilotCredentials = {
    refresh: refreshToken,
    access: token,
    // expires_at is seconds; subtract 5 minutes so we refresh before actual expiry.
    expires: expiresAt * 1000 - 5 * 60 * 1000,
  };
  if (enterpriseDomain) {
    credentials.enterpriseUrl = enterpriseDomain;
  }
  return credentials;
}

/**
 * Login with GitHub Copilot OAuth (device-code flow).
 *
 * Prompts for an optional GitHub Enterprise URL/domain, performs the device-code flow,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Log the parsed response object to identify which field is missing or mistyped
  2. Check for an error envelope (`message`, `documentation_url`) and re-authenticate via device flow if the GitHub token is no longer accepted
  3. If using GHES/Enterprise Copilot, verify the instance's `copilot_internal` API version matches what the SDK expects
  4. Update test fixtures/mocks to include both `token: string` and `expires_at: number` in seconds
  5. Upgrade the SDK after any GitHub internal API change so parsing matches the new shape

Example fix

// before: mock fixture missing fields breaks refresh
const body = { token: 'tid=...;exp=...;proxy-ep=...' };
// after: include the full expected payload with expires_at in seconds
const body = { token: 'tid=...;exp=1799999999;proxy-ep=proxy.individual.githubcopilot.com', expires_at: 1799999999 };
Defensive patterns

Strategy: type-guard

Validate before calling

// Confirm the token payload carries both required fields before passing it around
function hasCopilotTokenPayload(o: unknown): boolean {
  const r = o as Record<string, unknown> | null;
  return !!r && typeof r.token === 'string' && r.token.includes('proxy-ep=') && typeof r.expires_at === 'number' && r.expires_at > 0;
}

Type guard

function isGitHubCopilotTokenPayload(v: unknown): v is { token: string; expires_at: number } {
  if (!v || typeof v !== 'object') return false;
  const o = v as Record<string, unknown>;
  return typeof o.token === 'string' && o.token.length > 0 && typeof o.expires_at === 'number' && Number.isFinite(o.expires_at);
}

Try / catch

try {
  const creds = await provider.credentials();
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid Copilot token response fields') {
    // Log the payload keys to see which field is missing or mistyped, then re-auth
    console.error('Copilot token payload invalid:', e.message);
    return startFreshDeviceFlow();
  }
  throw e;
}

Prevention

When it happens

Trigger: The `/copilot_internal/v2/token` endpoint returned an object missing `token` or `expires_at` (or with a string `expires_at`), e.g. an error envelope `{message:"..."}` served with 200, a GHES/Copilot-for-Enterprise endpoint with a different payload version, or a proxy serving cached/partial JSON.

Common situations: GitHub changing or versioning the internal token endpoint shape, GHE Copilot endpoints diverging from github.com, mock servers or MSW fixtures returning incomplete token objects during development/testing.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/9f38043ccd9c5b0b. Report an issue: GitHub.