{"record":{"id":"8f53081472cdeabe","repo":"mastra-ai/mastra","slug":"xai-device-authorization-returned-a-non-https-veri","errorCode":null,"errorMessage":"xAI device authorization returned a non-https verification_uri: ${raw}","messagePattern":"xAI device authorization returned a non-https verification_uri: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/auth/providers/xai.ts","lineNumber":45,"sourceCode":"async function postForm(url: string, params: Record<string, string>, signal?: AbortSignal): Promise<Response> {\n  return fetch(url, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n    body: new URLSearchParams(params).toString(),\n    signal,\n  });\n}\n\n/** The verification URI is opened by the user; only accept https URLs. */\nfunction validateVerificationUri(raw: string): string {\n  let parsed: URL;\n  try {\n    parsed = new URL(raw);\n  } catch {\n    throw new Error(`xAI device authorization returned an invalid verification_uri: ${raw}`);\n  }\n  if (parsed.protocol !== 'https:') {\n    throw new Error(`xAI device authorization returned a non-https verification_uri: ${raw}`);\n  }\n  return parsed.toString();\n}\n\nfunction credentialsFromTokenResponse(data: unknown, previousRefreshToken?: string): OAuthCredentials {\n  const record = (data ?? {}) as Record<string, unknown>;\n  const access = record.access_token;\n  if (typeof access !== 'string' || access.length === 0) {\n    throw new Error('xAI token response missing access_token');\n  }\n\n  // xAI may not rotate the refresh token on refresh; keep the previous one.\n  const refresh =\n    typeof record.refresh_token === 'string' && record.refresh_token.length > 0\n      ? record.refresh_token\n      : previousRefreshToken;\n  if (!refresh) {\n    throw new Error('xAI token response missing refresh_token');","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/auth/providers/xai.ts#L27-L63","documentation":"validateVerificationUri only accepts https URLs for the verification_uri because users open it in a browser to authorize the device. A parseable URL with a non-https protocol (http:, javascript:, etc.) is rejected to prevent credential leakage or injection.","triggerScenarios":"startXAIDeviceLogin gets a device-authorization response where verification_uri / verification_uri_complete parses as a URL but parsed.protocol !== 'https:'.","commonSituations":"Provider misconfiguration returning http:// URLs; a local mock/stub server in development; a man-in-the-middle or compromised endpoint serving insecure URLs.","solutions":["Inspect the raw verification_uri in the response and confirm it starts with https://.","Remove any HTTP proxy/interception for xAI API hosts that could rewrite URLs.","Use only the official xAI device-code endpoint; verify no custom base URL override is set.","If the provider legitimately changed scheme, update/upgrade the SDK after confirming it is official."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":"function isHttpsUrl(raw: unknown): raw is string {\n  if (typeof raw !== 'string') return false;\n  try { return new URL(raw).protocol === 'https:'; } catch { return false; }\n}","tryCatchPattern":"try {\n  await openXaiVerificationPage(pending.url);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('non-https verification_uri')) {\n    // treat as potentially MITM'd/misconfigured provider; abort, never open the URL\n    abortDeviceLogin();\n  }\n}","preventionTips":["Never disable or bypass the https check on verification URLs","Use only the official xAI endpoints (no http mocks in production paths)","Route xAI API traffic through trusted, TLS-preserving networks only","If a provider change is suspected, verify the scheme change officially before updating code"],"tags":["oauth","xai","device-flow","security"],"backgroundTag":"non-https-url-rejected","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}