mastra-ai/mastra · error

Invalid device code response fields

Error message

Invalid device code response fields

What it means

After the device-code response parsed as an object, `startDeviceFlow` checks that `device_code`, `user_code`, `verification_uri` are strings and `interval`, `expires_in` are numbers. A missing or mistyped field means GitHub answered ok but the payload is not a valid device-code response, so the SDK refuses to continue the polling flow. This is a defensive schema validation against contract drift or non-GitHub responses.

Source

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

  if (!data || typeof data !== 'object') {
    throw new Error('Invalid device code response');
  }

  const obj = data as Record<string, unknown>;
  const deviceCode = obj.device_code;
  const userCode = obj.user_code;
  const verificationUri = obj.verification_uri;
  const interval = obj.interval;
  const expiresIn = obj.expires_in;

  if (
    typeof deviceCode !== 'string' ||
    typeof userCode !== 'string' ||
    typeof verificationUri !== 'string' ||
    typeof interval !== 'number' ||
    typeof expiresIn !== 'number'
  ) {
    throw new Error('Invalid device code response fields');
  }

  return {
    device_code: deviceCode,
    user_code: userCode,
    verification_uri: verificationUri,
    interval,
    expires_in: expiresIn,
  };
}

/** Sleep that can be interrupted by an AbortSignal. */
function abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {
  return new Promise((resolve, reject) => {
    if (signal?.aborted) {
      reject(new Error('Login cancelled'));
      return;
    }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Inspect the actual response object (log it before this call) to see which field is missing or mistyped
  2. Confirm the domain points at a real GitHub/GHES device-flow endpoint, not a proxy or mock
  3. Check for an error object in the response (`error`, `error_description`) and surface that message instead
  4. Upgrade the SDK — field validation may need updating after a GitHub API change
  5. File/verify against GHES release notes if using GitHub Enterprise Server, as its device-flow payload can lag github.com

Example fix

// before: swallowing the real payload
const d = await provider.device(); // throws 'Invalid device code response fields'
// after: capture and inspect the raw response to see the real error
const raw = await fetch(deviceCodeUrl, { method: 'POST', ... });
const body = await raw.json();
if (body.error) throw new Error(`GitHub: ${body.error} - ${body.error_description}`);
console.log(body); // then compare with expected device_code/user_code fields
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate the raw device-flow payload shape yourself before/alongside the SDK call
function looksLikeDeviceCode(o: unknown): boolean {
  return !!o && typeof o === 'object' && ['device_code','user_code','verification_uri','interval','expires_in'].every(k => k in (o as Record<string, unknown>));
}

Type guard

function isValidDeviceCodeFields(v: unknown): v is { device_code: string; user_code: string; verification_uri: string; interval: number; expires_in: number } {
  if (!v || typeof v !== 'object') return false;
  const o = v as Record<string, unknown>;
  return typeof o.device_code === 'string'
    && typeof o.user_code === 'string'
    && typeof o.verification_uri === 'string'
    && typeof o.interval === 'number'
    && typeof o.expires_in === 'number';
}

Try / catch

try {
  const pending = await provider.device();
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid device code response fields') {
    // Surface the raw payload to see the actual error envelope or field drift
    const raw = await fetchRawDeviceCode(); // your own diagnostic call
    if (raw && typeof raw === 'object' && 'error' in (raw as object)) {
      throw new Error(`GitHub device flow: ${(raw as any).error} - ${(raw as any).error_description}`);
    }
    throw new Error(`Device-code fields missing/mistyped: ${JSON.stringify(raw)}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: GitHub returns an object without the standard device-flow fields — e.g. an error object like `{error:"...", error_description:"..."}` delivered with a 200, a GHES instance with a divergent device-flow implementation, or an API version change renaming/omitting fields.

Common situations: GHES or GitHub proxy endpoints with older/newer device-flow implementations, interception by a mock or gateway returning partial JSON, GitHub deprecating/changing field types in a future API version.

Related errors


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