{"record":{"id":"99196a533a42dcf8","repo":"mastra-ai/mastra","slug":"github-cursor-must-be-a-positive-page-number","errorCode":null,"errorMessage":"GitHub cursor must be a positive page number.","messagePattern":"GitHub cursor must be a positive page number\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/github/integration.ts","lineNumber":1502,"sourceCode":"\nfunction getSingleSourceId(sourceIds: string[], message: string): string {\n  if (sourceIds.length !== 1) throw new Error(message);\n  return sourceIds[0]!;\n}\n\nfunction normalizeLabels(labels: string[] | undefined): string[] {\n  return [...new Set((labels ?? []).map(label => label.trim()).filter(Boolean))];\n}\n\nfunction requireSourceId(sourceId: string | undefined, message: string): string {\n  if (!sourceId) throw new Error(message);\n  return sourceId;\n}\n\nfunction parsePositiveCursor(cursor: string | undefined): number {\n  if (cursor === undefined) return 1;\n  const page = parsePositiveInteger(cursor);\n  if (page === null) throw new Error('GitHub cursor must be a positive page number.');\n  return page;\n}\n\nfunction parsePositiveInteger(value: string): number | null {\n  if (!/^\\d+$/.test(value)) return null;\n  const parsed = Number(value);\n  return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n  return typeof error === 'object' && error !== null && 'status' in error && error.status === 404;\n}\n\n/** Split an `owner/name` full name into its parts, or `null` when malformed. */\nfunction splitRepoFullName(repoFullName: string): { owner: string; repo: string } | null {\n  const slash = repoFullName.indexOf('/');\n  if (slash <= 0 || slash === repoFullName.length - 1) return null;\n  return { owner: repoFullName.slice(0, slash), repo: repoFullName.slice(slash + 1) };","sourceCodeStart":1484,"sourceCodeEnd":1520,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/github/integration.ts#L1484-L1520","documentation":"parsePositiveCursor converts a pagination cursor string into a page number, defaulting to page 1 when no cursor is given. A cursor that is present but not a valid positive integer (e.g. '0', '-2', 'abc') is rejected — cursors for this API are plain page numbers.","triggerScenarios":"Passing a next-page cursor from a different API (opaque token) into this GitHub pagination; manually constructing '0'; corrupted stored cursor value.","commonSituations":"Mixing cursor formats between integrations (opaque base64 cursors vs numeric pages); persisting a cursor and loading a truncated/garbage value; hardcoding page 0.","solutions":["Pass the numeric page string this library returned (e.g. '2'), or omit the cursor for the first page.","Do not feed opaque cursors from other APIs into GitHub pagination.","Validate the cursor is a positive integer before passing.","Clear stale stored cursors and restart pagination from the beginning."],"exampleFix":"// before\nlist({ cursor: opaqueTokenFromOtherApi });\n// after\nlist({ cursor: String(pageNumber) }); // e.g. '2'; omit for first page","handlingStrategy":"validation","validationCode":"if (cursor !== undefined && !/^\\d+$/.test(cursor)) throw new Error(`invalid page cursor: ${cursor}`);","typeGuard":"function isPageCursor(v: unknown): v is string {\n  return v === undefined || (typeof v === 'string' && /^\\d+$/.test(v) && Number(v) > 0);\n}","tryCatchPattern":"try {\n  return await list({ cursor });\n} catch (e) {\n  if ((e as Error).message.includes('cursor')) {\n    log.warn('bad cursor, restarting from page 1', { cursor });\n    return await list({});\n  }\n  throw e;\n}","preventionTips":["Only pass cursors returned by this library's pagination responses.","Don't mix opaque cursors from other APIs with numeric GitHub pages.","Validate persisted cursors on load and reset to page 1 if malformed."],"tags":["github","pagination","validation"],"backgroundTag":"invalid-pagination-cursor","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}