mastra-ai/mastra · error

Repository does not belong to the connection installation.

Error message

Repository does not belong to the connection installation.

What it means

Thrown by projectRepositories.link when the repository's installationId differs from the connection's installationId. A project repository link is only valid when both the connection and the repository are attached to the same source-control installation.

Source

Thrown at mastracode/factory/src/storage/domains/source-control/base.ts:853

                id: connection.factory_project_id,
                org_id: installation.org_id,
              });
              if (!project) continue;
              targets.push({
                orgId: installation.org_id,
                factoryProjectId: connection.factory_project_id,
                projectRepository: toProjectRepository(link),
              });
            }
          }
          return targets;
        },
        get: getProjectRepository,
        link: async input => {
          const connection = await requireConnection({ orgId: input.orgId, id: input.connectionId });
          const repository = await requireRepository({ orgId: input.orgId, id: input.repositoryId });
          if (repository.installationId !== connection.installationId) {
            throw new Error('Repository does not belong to the connection installation.');
          }
          const now = new Date();
          try {
            const row = await db().insertOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {
              connection_id: input.connectionId,
              repository_id: input.repositoryId,
              created_by_user_id: input.createdByUserId,
              branch: input.branch ?? null,
              sandbox_provider: input.sandboxProvider,
              sandbox_workdir: input.sandboxWorkdir,
              setup_command: input.setupCommand ?? null,
              teardown_command: input.teardownCommand ?? null,
              created_at: now,
              updated_at: now,
            });
            return toProjectRepository(row);
          } catch (error) {
            // Match the in-memory handle: return the existing row unchanged on

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Re-link after migrating the connection to the same installation (connections migrate or recreate)
  2. Call migrateInstallation on the repository to move it to the connection's installationId
  3. Recreate the connection under the repository's installation
  4. Verify installationIds match before linking

Example fix

// before
await forIntegration.projectRepositories.link({ orgId, connectionId, repositoryId });
// after
const conn = await forIntegration.connections.get({ orgId, id: connectionId });
const repo = await forIntegration.repositories.get({ orgId, id: repositoryId });
if (repo.installationId !== conn.installationId) {
  await api.migrateInstallation({ orgId, id: repositoryId, newInstallationId: conn.installationId });
}
await forIntegration.projectRepositories.link({ orgId, connectionId, repositoryId });
Defensive patterns

Strategy: validation

Validate before calling

const conn = await getConnection({ orgId, id: connectionId });
const repo = await getRepository({ orgId, id: repositoryId });
if (!conn || !repo) throw new Error('connection/repository missing');
if (repo.installationId !== conn.installationId) throw new Error('Installation mismatch before link');

Type guard

function sameInstallation(
  c: { installationId: string },
  r: { installationId: string }
): boolean {
  return c.installationId === r.installationId;
}

Try / catch

try {
  await link({ orgId, connectionId, repositoryId });
} catch (e) {
  if (e instanceof Error && e.message.includes('does not belong to the connection installation')) {
    await migrateInstallation({ orgId, id: repositoryId, newInstallationId: conn.installationId });
    await link({ orgId, connectionId, repositoryId });
  } else throw e;
}

Prevention

When it happens

Trigger: Linking a repository created under installation A to a connection created under installation B (e.g., after reinstalling the GitHub App or migrating only one side).

Common situations: GitHub App reinstall created a new installation ID; migrateInstallation moved a repo but the connection still points at the old installation; mixing repos across orgs/apps.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/0a7c04736af11482. Report an issue: GitHub.