mastra-ai/mastra · warning
GitHub cursor must be a positive page number.
Error message
GitHub cursor must be a positive page number.
What it means
Thrown by parsePositiveCursor when a pagination cursor is provided but is not a positive integer (fails parsePositiveInteger). GitHub list capabilities paginate by page number, so the cursor must be a positive integer string; absent cursor defaults to page 1.
Source
Thrown at mastracode/factory/src/integrations/platform/github/integration.ts:1565
function requireSingleSource(sourceIds: string[], message: string): string {
if (sourceIds.length !== 1) throw new Error(message);
return sourceIds[0]!;
}
function requireSource(sourceId: string | undefined, message: string): string {
if (!sourceId) throw new Error(message);
return sourceId;
}
function normalizeLabels(labels: string[] | undefined): string[] {
return [...new Set((labels ?? []).map(label => label.trim()).filter(Boolean))];
}
function parsePositiveCursor(cursor: string | undefined): number {
if (cursor === undefined) return 1;
const parsed = parsePositiveInteger(cursor);
if (parsed === null) throw new Error('GitHub cursor must be a positive page number.');
return parsed;
}
function parsePositiveInteger(value: string): number | null {
if (!/^\d+$/.test(value)) return null;
const parsed = Number(value);
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
}
function parseGithubExternalTarget(externalId: string): { repository: string; issueId: string } | null {
const match =
externalId.match(/^(.+\/.+):(\d+)$/) ??
externalId.match(/^github:(\d+):(?:issue|pull-request):(\d+)$/) ??
externalId.match(/^(\d+):(\d+)$/);
if (!match?.[1] || !match[2] || parsePositiveInteger(match[2]) === null) return null;
return { repository: match[1], issueId: match[2] };
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Omit the cursor entirely (or pass undefined) to fetch page 1
- Only pass through the exact nextCursor string returned by a previous call
- Validate the cursor is /^[1-9]\d*$/ before calling
- Clear stale client-side pagination state and restart listing from page 1
Example fix
// before
await github.listIssues({ installationId, sourceId, cursor: '0' });
// after
await github.listIssues({ installationId, sourceId }); // first page
// or: cursor: previousResponse.nextCursor Defensive patterns
Strategy: validation
Validate before calling
function safeCursor(cursor?: string): number | undefined {
if (cursor === undefined) return undefined;
if (!/^[1-9]\d*$/.test(cursor)) throw new Error(`invalid cursor: ${cursor}`);
return Number(cursor);
} Try / catch
try {
return await github.listIssues({ installationId, sourceId, cursor });
} catch (err) {
if (err instanceof Error && err.message.includes('positive page number')) {
return await github.listIssues({ installationId, sourceId }); // restart at page 1
} else throw err;
} Prevention
- Only pass through nextCursor values returned by the same integration
- Never hand-craft cursors or reuse cursors across providers
- Persist cursors opaquely and reset pagination state on decode failures
- Treat page 1 (omitted cursor) as the fallback
When it happens
Trigger: Passing cursor values like 'abc', '0', '-1', '1.5', or '' (non-undefined but invalid) into a paginated GitHub list capability.
Common situations: Echoing back a malformed nextCursor from a previous response; client-side cursor corruption; using an opaque cursor from a different integration's pagination scheme; passing 0 as the first page.
Related errors
- GitHub cursor must be a positive page number.
- Invalid knowledge node cursor.
- Knowledge node cursor does not match the active browse filte
- CursorSDKAgent resumeData must include a message.
- CursorSDKAgent resumeData.agentId must be a string when prov
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/65540b45c9ea2cca.
Report an issue: GitHub.