mastra-ai/mastra · error · Error
Repository access did not include a bearer token for the Fac
Error message
Repository access did not include a bearer token for the Factory session.
What it means
refreshGithubToken fetches repository access from the version-control backend and expects the response to carry an authorization token that can be injected into the Factory session's GitHub client. If getRepositoryAccess succeeds but returns no bearer token, the session cannot authenticate to GitHub, so the code throws rather than proceeding with an unauthenticated client. This indicates the token grant layer did not produce credentials for this org/repository pair.
Source
Thrown at mastracode/factory/src/integrations/github/session-subscriptions.ts:216
// `GH_TOKEN` feeds the `gh` CLI, so a configured org PAT wins over a minted
// installation token (which 403s on integration-restricted endpoints). The
// workspace records which PAT kind the sandbox was provisioned with, so a
// review-board sandbox keeps its reviewer token on refresh.
const pat = await getGithubPat(
() => github.integrationStorage,
target.orgId,
getRegisteredGithubPatKind(requestContext),
);
if (pat) {
injectGithubToken(requestContext, pat);
return;
}
const access = await github.versionControl.getRepositoryAccess({
orgId: target.orgId,
repositoryId: target.repository.id,
});
const token = access.authorization?.token;
if (!token) throw new Error('Repository access did not include a bearer token for the Factory session.');
injectGithubToken(requestContext, token);
}
export function createGithubSubscriptionTools(requestContext: RequestContext, github: GithubIntegration) {
if (!isGithubProjectSession(requestContext)) return {};
return {
github_refresh_token: createTool({
id: 'github_refresh_token',
description:
'Refresh GitHub CLI authentication in the active Factory sandbox. Use this after a gh command fails because authentication is expired, invalid, or missing. It installs a fresh GH_TOKEN for subsequent sandbox commands. After this tool succeeds, retry the failed gh command. Takes no arguments and never returns the token.',
inputSchema: z.object({}),
execute: async () => {
await refreshGithubToken(requestContext, github);
return { refreshed: true };
},
}),
github_upsert_factory_triage_comment: createTool({View on GitHub (pinned to 75dd419e61)
Solutions
- Re-authorize/re-install the GitHub App for the org so a fresh repository access token can be issued
- Check the credential/token store backing getRepositoryAccess for the given orgId+repositoryId and ensure a token exists and is unexpired
- Confirm the repository ID belongs to the org passed in — a mismatched org/repository pair can resolve access without authorization
- Add a token-presence check before calling refreshGithubToken and skip/re-queue token refresh when none is available
Example fix
// before
const access = await github.versionControl.getRepositoryAccess({ orgId, repositoryId });
if (!access.authorization?.token) throw new Error('no token');
// after
const access = await github.versionControl.getRepositoryAccess({ orgId, repositoryId });
if (!access.authorization?.token) {
logger.warn('No repository token for %s/%s — re-authorizing GitHub installation', orgId, repositoryId);
await reconnectGithubInstallation(orgId);
return;
} Defensive patterns
Strategy: validation
Validate before calling
const access = await github.versionControl.getRepositoryAccess({ orgId, repositoryId });
if (!access.authorization?.token) {
throw new Error('No repository token available — re-authorize the GitHub installation.');
} Type guard
function hasBearerToken(access: unknown): access is { authorization: { token: string } } {
return typeof access === 'object' && access !== null &&
'authorization' in access && typeof (access as any).authorization?.token === 'string' &&
(access as any).authorization.token.length > 0;
} Try / catch
try {
await refreshGithubToken(requestContext, github);
} catch (err) {
if ((err as Error).message.includes('did not include a bearer token')) {
await reconnectGithubInstallation(target.orgId);
return;
}
throw err;
} Prevention
- Monitor GitHub App installation/authorization revocation events and re-auth proactively
- Verify org+repository pairing before requesting repository access
- Check token expiry in the credential store and refresh before it lapses
- Log empty authorization payloads from getRepositoryAccess to catch backend regressions
When it happens
Trigger: Calling refreshGithubToken (wired into the GitHub subscription tools) when github.versionControl.getRepositoryAccess({ orgId, repositoryId }) resolves with access.authorization undefined or access.authorization.token empty.
Common situations: The GitHub App installation lost its token grant ( revoked permissions, expired installation); the org has no credentials registered for that repository; backend/auth service returns a 200 with an empty authorization payload; the repository was moved or deleted so access resolution silently returns no auth.
Related errors
- GitHub OAuth token exchange returned no token: ${data.error_
- GitHub capabilities require an app-installation connection.
- Repository access did not include a bearer token.
- GitHub subscriptions require an authenticated repository ses
- The active sandbox provider does not support runtime GitHub
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f5756a43c8e9b755.
Report an issue: GitHub.