{"record":{"id":"b9ef9547b3882f87","repo":"mastra-ai/mastra","slug":"not-logged-in-to-github-copilot","errorCode":null,"errorMessage":"Not logged in to GitHub Copilot.","messagePattern":"Not logged in to GitHub Copilot\\.","errorType":"exception","errorClass":"ProviderAuthRequiredError","httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/providers/github-copilot.ts","lineNumber":127,"sourceCode":"}\n\n/**\n * Build a fetch wrapper that authenticates with GitHub Copilot OAuth.\n *\n * - Injects the short-lived Copilot bearer token (auto-refreshed by AuthStorage).\n * - Adds the VS Code-like Copilot headers required by the API.\n * - Rewrites the request URL onto the per-token API base when `rewriteUrl` is true.\n */\nexport function buildGitHubCopilotOAuthFetch(\n  opts: { authStorage?: CredentialStore; rewriteUrl?: boolean } = {},\n): typeof fetch {\n  return (async (url: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {\n    const storage = opts.authStorage ?? getAuthStorage();\n    storage.reload();\n\n    const cred = storage.get(COPILOT_PROVIDER_ID);\n    if (!cred || cred.type !== 'oauth') {\n      throw new ProviderAuthRequiredError('Not logged in to GitHub Copilot.');\n    }\n\n    // getApiKey() refreshes the Copilot bearer if it has expired.\n    const accessToken = await storage.getApiKey(COPILOT_PROVIDER_ID);\n    if (!accessToken) {\n      throw new ProviderAuthRequiredError('Failed to refresh the GitHub Copilot token.');\n    }\n    storage.reload();\n\n    const enterpriseUrl = (cred as GitHubCopilotCredentials).enterpriseUrl;\n\n    let parsedBody: unknown;\n    if (typeof init?.body === 'string') {\n      try {\n        parsedBody = JSON.parse(init.body);\n      } catch {\n        parsedBody = undefined;\n      }","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/providers/github-copilot.ts#L109-L145","documentation":"The GitHub Copilot OAuth fetch wrapper requires a stored credential of type 'oauth' for the copilot provider. If auth storage contains no credential or a non-OAuth credential, ProviderAuthRequiredError('Not logged in to GitHub Copilot.') is thrown before any token refresh or network request. It means the user has not completed the Copilot device-flow login.","triggerScenarios":"Using `copilot` or `fetchWithOAuth` for GitHub Copilot when `storage.get(COPILOT_PROVIDER_ID)` returns undefined, or returns a credential whose type is not 'oauth' (e.g. an api_key entry or a legacy/stale record).","commonSituations":"Never completed the GitHub Copilot device-code login on this machine; auth storage cleared or relocated (different HOME in CI); GitHub Copilot subscription absent so login flow failed silently; mixing provider ids so the credential is stored under a different key.","solutions":["Run the GitHub Copilot OAuth/device-flow login and ensure the credential is stored under COPILOT_PROVIDER_ID","Verify storage contents after login (`storage.get('github-copilot')` should be type 'oauth')","Catch ProviderAuthRequiredError and trigger the interactive login before retrying","In CI, provision the credential file or inject auth storage from a secret"],"exampleFix":"// before\nconst provider = copilot(); // throws if no oauth cred\n// after\nconst cred = storage.get('github-copilot');\nif (!cred || cred.type !== 'oauth') {\n  await copilotDeviceFlowLogin(); // stores oauth credential\n}\nconst provider = copilot();","handlingStrategy":"validation","validationCode":"storage.reload();\nconst cred = storage.get('github-copilot');\nif (!cred || cred.type !== 'oauth') {\n  throw new Error('GitHub Copilot OAuth login required (run the device-flow login).');\n}","typeGuard":"function isCopilotOAuthCred(c: unknown): c is { type: 'oauth'; enterpriseUrl?: string } {\n  return typeof c === 'object' && c !== null && (c as { type?: string }).type === 'oauth';\n}","tryCatchPattern":"try {\n  await runWithCopilot();\n} catch (err) {\n  if (err instanceof ProviderAuthRequiredError && err.message.includes('Not logged in')) {\n    await copilotDeviceFlowLogin();\n  } else throw err;\n}","preventionTips":["Complete the Copilot device-flow login before first use on any machine","Verify the stored credential type is 'oauth' (not api_key) under the copilot provider id","Persist auth storage across CI runs or inject it as a secret","Confirm the GitHub account has an active Copilot subscription"],"tags":["auth","oauth","github-copilot"],"backgroundTag":"oauth-not-logged-in","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}