mastra-ai/mastra · error
Unsupported GitHub review state: ${state}
Error message
Unsupported GitHub review state: ${state} What it means
parseReviewState maps GitHub's uppercase review state strings onto the library's Review['state'] union. Any state string outside the five known GitHub values (PENDING, COMMENTED, APPROVED, CHANGES_REQUESTED, DISMISSED) is rejected, meaning GitHub introduced a new state or the caller passed an already-lowercased/invalid value.
Source
Thrown at mastracode/factory/src/integrations/github/integration.ts:1459
function parseRequestedReviewers(data: {
users?: Array<{ login?: string }> | null;
teams?: Array<{ slug?: string }> | null;
requested_reviewers?: Array<{ login?: string }> | null;
requested_teams?: Array<{ slug?: string }> | null;
}) {
return {
users: (data.users ?? data.requested_reviewers ?? []).flatMap(user => (user.login ? [user.login] : [])),
teams: (data.teams ?? data.requested_teams ?? []).flatMap(team => (team.slug ? [team.slug] : [])),
};
}
function parseReviewState(state: string): Review['state'] {
if (state === 'PENDING') return 'pending';
if (state === 'COMMENTED') return 'commented';
if (state === 'APPROVED') return 'approved';
if (state === 'CHANGES_REQUESTED') return 'changes-requested';
if (state === 'DISMISSED') return 'dismissed';
throw new Error(`Unsupported GitHub review state: ${state}`);
}
function reviewEventToGithub(event: Exclude<InputOf<'createReview'>['event'], undefined>) {
if (event === 'approve') return 'APPROVE' as const;
if (event === 'request-changes') return 'REQUEST_CHANGES' as const;
return 'COMMENT' as const;
}
function requirePullRequestNumber(value: string): number {
return requirePositiveId(value, 'pull request');
}
function requirePositiveId(value: string, resource: string): number {
const parsed = parsePositiveInteger(value);
if (parsed === null) throw new Error(`GitHub ${resource} id must be a positive integer.`);
return parsed;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Pass the raw uppercase state from the GitHub API, not a normalized value.
- Log the offending state value and check the GitHub REST API docs for new states.
- Add a mapping branch for any newly documented state.
- Map unknown states to a fallback like 'commented' only if your logic tolerates it — better to update the parser.
Example fix
// before parseReviewState(review.state.toLowerCase()); // after parseReviewState(review.state); // pass raw API value, e.g. 'CHANGES_REQUESTED'
Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = ['PENDING','COMMENTED','APPROVED','CHANGES_REQUESTED','DISMISSED'] as const;
if (!(KNOWN as readonly string[]).includes(state)) throw new Error(`unknown review state: ${state}`); Type guard
function isGithubReviewState(s: string): s is 'PENDING'|'COMMENTED'|'APPROVED'|'CHANGES_REQUESTED'|'DISMISSED' {
return ['PENDING','COMMENTED','APPROVED','CHANGES_REQUESTED','DISMISSED'].includes(s);
} Try / catch
try {
return parseReviewState(rawState);
} catch (e) {
log.warn('unknown review state', { rawState });
return 'commented' as Review['state']; // or rethrow, per policy
} Prevention
- Pass raw uppercase GitHub API values straight into the parser.
- Keep a mapping table checked against current GitHub REST docs.
- Don't cache normalized states and re-run them through the parser.
When it happens
Trigger: Fetching PR reviews while passing a custom state string; GitHub API returning an unexpected new state value; feeding lowercase 'approved' into parseReviewState instead of the raw API value.
Common situations: Caching review states and re-parsing stored (normalized) values; a GitHub API change adding a state; passing review.submitted state from a different API shape.
Related errors
- Invalid state token payload
- Failed to parse A2A stream event: ${error instanceof Error ?
- Version-control repository not found.
- Version-control installation not found.
- GitHub installation id is invalid.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6b771845b153d1f4.
Report an issue: GitHub.