{"record":{"id":"a99f1d721fa5f8d6","repo":"mastra-ai/mastra","slug":"github-resource-id-must-be-a-positive-integer-a99f1d","errorCode":null,"errorMessage":"GitHub ${resource} id must be a positive integer.","messagePattern":"GitHub (.+?) id must be a positive integer\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/platform/github/integration.ts","lineNumber":1594,"sourceCode":"  const match =\n    externalId.match(/^(.+\\/.+):(\\d+)$/) ??\n    externalId.match(/^github:(\\d+):(?:issue|pull-request):(\\d+)$/) ??\n    externalId.match(/^(\\d+):(\\d+)$/);\n  if (!match?.[1] || !match[2] || parsePositiveInteger(match[2]) === null) return null;\n  return { repository: match[1], issueId: match[2] };\n}\n\nfunction optionalPositiveIntegerEnv(name: 'MASTRA_PLATFORM_GITHUB_POLLING_INTERVAL_MS'): number | undefined {\n  const value = process.env[name]?.trim();\n  if (!value) return undefined;\n  const parsed = parsePositiveInteger(value);\n  if (parsed === null) throw new Error(`${name} must be a positive integer.`);\n  return parsed;\n}\n\nfunction requirePositiveId(value: string, resource: string): number {\n  const parsed = parsePositiveInteger(value);\n  if (parsed === null) throw new Error(`GitHub ${resource} id must be a positive integer.`);\n  return parsed;\n}\n\nfunction reviewEvent(event: 'approve' | 'request-changes' | 'comment') {\n  if (event === 'approve') return 'APPROVE' as const;\n  if (event === 'request-changes') return 'REQUEST_CHANGES' as const;\n  return 'COMMENT' as const;\n}\n\nfunction isNotFound(error: unknown): boolean {\n  return error instanceof PlatformApiError && error.status === 404;\n}\n\n// Platform answers 404 when the installation row is gone, 409 when it is suspended or soft-deleted.\n// A 502 also covers a dead installation but is indistinguishable from a transient GitHub outage.\nfunction isDeadInstallation(error: unknown): boolean {\n  return error instanceof PlatformApiError && (error.status === 404 || error.status === 409);\n}","sourceCodeStart":1576,"sourceCodeEnd":1612,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/platform/github/integration.ts#L1576-L1612","documentation":"Thrown by requirePositiveId when a resource id string (e.g. pull request, issue, review comment id) does not parse as a positive integer. The helper is used across GitHub capabilities to coerce string ids into numeric GitHub REST identifiers before building request paths; the thrown message names the specific resource.","triggerScenarios":"Calling a capability with an id argument like 'abc', '', '0', 'PR-123', or a global platform id (e.g. a UUID) where a numeric GitHub object id is expected — via requirePositiveId(value, resource).","commonSituations":"Passing a platform/database surrogate key instead of the GitHub numeric id; string interpolation lost digits or added prefixes; UI state held a display label ('#42') instead of the raw id; ids from another provider (GitLab issue number vs GitHub id).","solutions":["Pass the raw numeric GitHub object id as a digit-only string (e.g. '1234567890')","Map the platform record to its stored GitHub external numeric id before calling","Strip display prefixes like '#' or 'PR-' before invocation","Validate the id with /^\\d+$/ in the calling layer to fail earlier with clearer context"],"exampleFix":"// before\nawait github.mergePullRequest({ installationId, sourceId, pullRequestId: 'PR-42' });\n// after\nawait github.mergePullRequest({ installationId, sourceId, pullRequestId: '1234567890' });","handlingStrategy":"validation","validationCode":"function requireNumericId(value: string, what: string): number {\n  if (!/^\\d+$/.test(value) || Number(value) <= 0) throw new Error(`${what} must be a numeric GitHub id, got: ${value}`);\n  return Number(value);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await github.mergePullRequest({ installationId, sourceId, pullRequestId });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('id must be a positive integer')) {\n    pullRequestId = await mapPlatformIdToGithubId(pullRequestId);\n    // retry once with the corrected id\n  } else throw err;\n}","preventionTips":["Persist the numeric GitHub object id (external id) on platform records and use it for API calls","Strip display prefixes ('#', 'PR-') before passing ids","Keep GitHub ids as digit-only strings end-to-end; never substitute surrogate keys","Add contract tests asserting ids passed to GitHub capabilities match /^\\d+$/"],"tags":["github","validation","id-parsing","pull-request"],"backgroundTag":"invalid-identifier-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}