mastra-ai/mastra · error
Failed to load GitHub token status (${res.status})
Error message
Failed to load GitHub token status (${res.status}) What it means
fetchGithubPatStatus fetches `${baseUrl}/web/github/pat` and throws `Failed to load GitHub token status (${res.status})` when the response is not ok. It reports that the GitHub PAT status endpoint rejected the request; only the HTTP status is included, with no server message parsing.
Source
Thrown at mastracode/factory-ui/src/ui/domains/workspaces/services/github.ts:158
/** `default` = the worker token every sandbox gets; `reviewer` = optional
* token review-board sessions use so PR reviews come from another account. */
export type GithubPatKind = 'default' | 'reviewer';
export interface GithubPatStatus {
configured: boolean;
reviewerConfigured: boolean;
}
/**
* Which GitHub Personal Access Tokens the org has configured for `gh` CLI
* use in sandboxes. The tokens themselves never reach the browser.
*/
export async function fetchGithubPatStatus(baseUrl: string): Promise<GithubPatStatus> {
const res = await fetch(`${baseUrl}/web/github/pat`, {
headers: { Accept: 'application/json' },
credentials: 'include',
});
if (!res.ok) throw new Error(`Failed to load GitHub token status (${res.status})`);
return (await res.json()) as GithubPatStatus;
}
/** Save an org GitHub PAT (used only for `gh` CLI auth in sandboxes). */
export async function saveGithubPat(baseUrl: string, token: string, kind: GithubPatKind = 'default'): Promise<void> {
const res = await fetch(`${baseUrl}/web/github/pat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
credentials: 'include',
body: JSON.stringify({ token, kind }),
});
if (!res.ok) {
const body = (await res.json().catch(() => undefined)) as { error?: string } | undefined;
throw new Error(body?.error ?? `Failed to save GitHub token (${res.status})`);
}
}
/** Remove an org GitHub PAT. */View on GitHub (pinned to 75dd419e61)
Solutions
- Check the status in the message: 401/403 -> re-authenticate and ensure cookies are sent (credentials: 'include' needs CORS credential support).
- Verify baseUrl points at the deployment that serves /web/github/pat (404 indicates a wrong base URL or missing route).
- Retry with React Query's built-in retry/backoff for transient 5xx/network failures.
- Inspect server logs for the backend error if the status is 500.
Example fix
// before
const status = await fetchGithubPatStatus(baseUrl);
// after
const { data, error } = useGithubPatStatusQuery(baseUrl);
if (error instanceof Error && /\((\d{3})\)/.test(error.message) && error.message.endsWith('(401)')) {
redirectToLogin();
} Defensive patterns
Strategy: retry
Validate before calling
// verify baseUrl serves the endpoint before querying
const reachable = await fetch(`${baseUrl}/web/github/pat`, { method: 'HEAD', credentials: 'include' }).then(r => r.status !== 404).catch(() => false);
if (!reachable) throw new Error('GitHub PAT endpoint unavailable: check baseUrl/deployment'); Type guard
function isGithubPatStatus(x: unknown): x is GithubPatStatus {
return typeof x === 'object' && x !== null && 'hasToken' in x;
} Try / catch
useQuery({
queryKey: ['github-pat-status', baseUrl],
queryFn: () => fetchGithubPatStatus(baseUrl),
retry: (count, e) => {
const m = /\((\d{3})\)/.exec((e as Error).message);
const status = m ? Number(m[1]) : 0;
return count < 3 && (status === 0 || status >= 500);
},
onError: (e: Error) => {
if (e.message.endsWith('(401)')) redirectToLogin();
},
}); Prevention
- Configure React Query retries only for transient statuses (0/network, 5xx); never retry 401/403/404.
- Treat 401 from the PAT status query as a session-expiry signal and trigger re-login.
- Validate baseUrl per environment (dev/staging/prod) before mounting queries that hit /web/github/pat.
- Keep cookies flowing for cross-origin deployments via proper CORS credentials configuration.
When it happens
Trigger: useGithubPatStatusQuery runs and the endpoint returns non-2xx: 401/403 when the session cookie is missing/expired or the caller lacks org access, 404 when the /web/github/pat route isn't deployed or baseUrl is wrong, or 5xx from a backend failure.
Common situations: Session expired while the dashboard polls token status, wrong baseUrl/proxy in dev causing 404, org without GitHub integration configured hitting an unauthorized route, or backend outage returning 502/503 through a proxy.
Related errors
- Failed to fetch CDP version info from ${versionUrl}: ${respo
- GitHub OAuth token exchange failed: ${res.status}
- GitHub OAuth token exchange returned no token: ${data.error_
- GitHub capabilities require an app-installation connection.
- Repository access did not include a bearer token.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/70c7d1c56d482720.
Report an issue: GitHub.