{"record":{"id":"3c52d9eb0a19eae8","repo":"mastra-ai/mastra","slug":"source-control-connection-or-repository-not-found","errorCode":null,"errorMessage":"Source-control connection or repository not found","messagePattern":"Source-control connection or repository not found","errorType":"exception","errorClass":null,"httpStatus":404,"severity":"error","filePath":"mastracode/factory/src/storage/domains/source-control/inmemory.ts","lineNumber":280,"sourceCode":"          targets.push({\n            orgId: installation.orgId,\n            factoryProjectId: connection.factoryProjectId,\n            projectRepository,\n          });\n        }\n      }\n      return targets;\n    },\n    get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectRepository | null> => {\n      const row = this.projectRepositoriesRows.find(candidate => candidate.id === id);\n      if (!row) return null;\n      return (await this.connections.get({ orgId, id: row.connectionId })) ? row : null;\n    },\n    link: async (input: LinkProjectRepositoryInput): Promise<ProjectRepository> => {\n      const connection = await this.connections.get({ orgId: input.orgId, id: input.connectionId });\n      const repository = await this.repositories.get({ orgId: input.orgId, id: input.repositoryId });\n      if (!connection || !repository || repository.installationId !== connection.installationId) {\n        throw new Error('Source-control connection or repository not found');\n      }\n      const existing = this.projectRepositoriesRows.find(\n        row => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId,\n      );\n      if (existing) return existing;\n      const now = new Date();\n      const created: ProjectRepository = {\n        id: randomUUID(),\n        connectionId: input.connectionId,\n        repositoryId: input.repositoryId,\n        createdByUserId: input.createdByUserId,\n        branch: input.branch ?? null,\n        sandboxProvider: input.sandboxProvider,\n        sandboxWorkdir: input.sandboxWorkdir,\n        setupCommand: input.setupCommand ?? null,\n        teardownCommand: input.teardownCommand ?? null,\n        createdAt: now,\n        updatedAt: now,","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/storage/domains/source-control/inmemory.ts#L262-L298","documentation":"Thrown by the in-memory projectRepositories.link when the connection or repository cannot be found, or when the repository's installationId does not match the connection's installationId. This single guard covers all invalid link preconditions.","triggerScenarios":"Linking with a nonexistent connectionId or repositoryId, ids from different orgs, or a repo whose installation differs from the connection's installation.","commonSituations":"Mixing fixtures between orgs; installation mismatch after GitHub App reinstall; linking before creating both records.","solutions":["Verify both connection and repository exist via connections.get and repositories.get before linking","Align installationIds (migrate the repo or recreate the connection) so they match","Recreate missing records (connection or repository) before linking"],"exampleFix":"// before\nawait storage.projectRepositories.link({ orgId, connectionId, repositoryId });\n// after\nconst [conn, repo] = await Promise.all([\n  storage.connections.get({ orgId, id: connectionId }),\n  storage.repositories.get({ orgId, id: repositoryId }),\n]);\nif (!conn || !repo) throw new Error('Create connection and repository first');\nif (repo.installationId !== conn.installationId) throw new Error('Installation mismatch');\nawait storage.projectRepositories.link({ orgId, connectionId, repositoryId });","handlingStrategy":"validation","validationCode":"const conn = await storage.connections.get({ orgId, id: connectionId });\nconst repo = await storage.repositories.get({ orgId, id: repositoryId });\nif (!conn || !repo) throw new Error('Both connection and repository must exist');\nif (repo.installationId !== conn.installationId) throw new Error('Installation mismatch');","typeGuard":"function linkable(\n  c: { installationId: string } | null,\n  r: { installationId: string } | null\n): r is { installationId: string } {\n  return !!c && !!r && c.installationId === r.installationId;\n}","tryCatchPattern":"try {\n  await storage.projectRepositories.link({ orgId, connectionId, repositoryId });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('connection or repository not found')) {\n    throw new Error('Create/migrate connection and repository under one installation before linking');\n  } else throw e;\n}","preventionTips":["Create connection and repository before linking","Keep both records under the same installation","Scope fixture ids to a single org to avoid lookup misses"],"tags":["source-control","not-found","installation-mismatch","link","in-memory"],"backgroundTag":"resource-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}