{"record":{"id":"c236e0406c22aed0","repo":"mastra-ai/mastra","slug":"version-control-installation-not-found-c236e0","errorCode":null,"errorMessage":"Version-control installation not found.","messagePattern":"Version-control installation not found\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/platform/github/integration.ts","lineNumber":395,"sourceCode":"              providerMetadata: repository.metadata,\n            },\n          }),\n        ),\n      ),\n    getRepositoryAccess: async ({ orgId, repositoryId }) => {\n      // Every session materialization requests access; reuse a recent grant\n      // instead of re-minting through the Platform each time. The TTL keeps\n      // a wide margin under GitHub's ~60min installation-token lifetime.\n      const cacheKey = `${orgId}:${repositoryId}`;\n      const cached = this.#repositoryAccessCache.get(cacheKey);\n      if (cached && cached.expiresAt > Date.now()) return cached.access;\n      this.#repositoryAccessCache.delete(cacheKey);\n\n      const repository = await this.storage.repositories.get({ orgId, id: repositoryId });\n      if (!repository) throw new Error('Version-control repository not found.');\n      const cloneUrl = `https://github.com/${repository.slug}.git`;\n      const installation = await this.storage.installations.get({ orgId, id: repository.installationId });\n      if (!installation) throw new Error('Version-control installation not found.');\n      const installationId = parsePositiveInteger(installation.externalId);\n      if (installationId === null) throw new Error('GitHub installation id is invalid.');\n      const repositoryName = splitRepository(repository.slug).repo;\n\n      try {\n        const token = await this.#client.request<{ token: string }>(\n          'POST',\n          `${API_PREFIX}/github-app/installations/${installationId}/token`,\n          { repositories: [repositoryName], permissions: REPOSITORY_TOKEN_PERMISSIONS },\n        );\n        const access: RepositoryAccess = {\n          cloneUrl,\n          authorization: { scheme: 'bearer', token: token.token },\n        };\n        setBounded(this.#repositoryAccessCache, cacheKey, {\n          access,\n          expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS,\n        });","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/platform/github/integration.ts#L377-L413","documentation":"Thrown by PlatformGithubIntegration.getRepositoryAccess when the local installation record referenced by repository.installationId cannot be found in storage. The library stores repositories and their owning GitHub App installations as separate rows; a repository row pointing at a missing installation row means stale or inconsistent linkage data, so no installation token can be minted.","triggerScenarios":"Calling getRepositoryAccess (directly or via session materialization) for a repository whose installationId does not resolve to an installation row in this.storage.installations.get({ orgId, id }).","commonSituations":"The GitHub App was uninstalled and the installation row was deleted (or a reinstall created a new installation row) while the repository row still references the old installation id; manual DB cleanup or a partial sync removed the installation; cross-org id mismatch.","solutions":["Re-run the integration's source sync (intake.listSources) so the repository row is relinked to the current installation row","Check storage for the installation row: verify an installation exists with id === repository.installationId in the same org","If the app was reinstalled, update repository.installationId to the new installation's id","Restore the deleted installation row from backup or recreate it via the app-installation webhook"],"exampleFix":"// before (stale reference)\nawait storage.repositories.update({ orgId, id: repositoryId, installationId: OLD_INSTALLATION_ID });\n// after (relink to reinstalled app installation)\nconst installation = await storage.installations.getByExternalId({ orgId, externalId: newGithubInstallationId });\nawait storage.repositories.update({ orgId, id: repositoryId, installationId: installation.id });","handlingStrategy":"try-catch","validationCode":"const repo = await storage.repositories.get({ orgId, id: repositoryId });\nif (!repo) throw new Error('repository not found');\nconst installation = await storage.installations.get({ orgId, id: repo.installationId });\nif (!installation) throw new Error(`installation ${repo.installationId} missing for repository ${repositoryId}`);","typeGuard":null,"tryCatchPattern":"try {\n  const access = await github.getRepositoryAccess({ orgId, repositoryId });\n} catch (err) {\n  if (err instanceof Error && err.message === 'Version-control installation not found.') {\n    await resyncSources(orgId); // relink repository to current installation\n  } else throw err;\n}","preventionTips":["Re-sync sources after any GitHub App uninstall/reinstall","Use cascading deletes or referential checks so repository rows never outlive their installation row","Monitor for orphaned repository rows with a periodic integrity query","Persist the GitHub installation external id so rows can be re-linked deterministically"],"tags":["github","installation","data-integrity","storage"],"backgroundTag":"stale-installation-reference","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}