mastra-ai/mastra · error
Source-control connection or repository not found
Error message
Source-control connection or repository not found
What it means
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.
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
Example fix
// before
await storage.projectRepositories.link({ orgId, connectionId, repositoryId });
// after
const [conn, repo] = await Promise.all([
storage.connections.get({ orgId, id: connectionId }),
storage.repositories.get({ orgId, id: repositoryId }),
]);
if (!conn || !repo) throw new Error('Create connection and repository first');
if (repo.installationId !== conn.installationId) throw new Error('Installation mismatch');
await storage.projectRepositories.link({ orgId, connectionId, repositoryId }); Defensive patterns
Strategy: validation
Validate before calling
const conn = await storage.connections.get({ orgId, id: connectionId });
const repo = await storage.repositories.get({ orgId, id: repositoryId });
if (!conn || !repo) throw new Error('Both connection and repository must exist');
if (repo.installationId !== conn.installationId) throw new Error('Installation mismatch'); Type guard
function linkable(
c: { installationId: string } | null,
r: { installationId: string } | null
): r is { installationId: string } {
return !!c && !!r && c.installationId === r.installationId;
} Try / catch
try {
await storage.projectRepositories.link({ orgId, connectionId, repositoryId });
} catch (e) {
if (e instanceof Error && e.message.includes('connection or repository not found')) {
throw new Error('Create/migrate connection and repository under one installation before linking');
} else throw e;
} Prevention
- Create connection and repository before linking
- Keep both records under the same installation
- Scope fixture ids to a single org to avoid lookup misses
When it happens
Trigger: Linking with a nonexistent connectionId or repositoryId, ids from different orgs, or a repo whose installation differs from the connection's installation.
Common situations: Mixing fixtures between orgs; installation mismatch after GitHub App reinstall; linking before creating both records.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Repository does not belong to the connection installation.
- Repository not found in organization
- Source-control installation not found
- Agent with id not found
- Dataset not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3c52d9eb0a19eae8.
Report an issue: GitHub.
Appendix: source
Thrown at mastracode/factory/src/storage/domains/source-control/inmemory.ts:280
targets.push({
orgId: installation.orgId,
factoryProjectId: connection.factoryProjectId,
projectRepository,
});
}
}
return targets;
},
get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectRepository | null> => {
const row = this.projectRepositoriesRows.find(candidate => candidate.id === id);
if (!row) return null;
return (await this.connections.get({ orgId, id: row.connectionId })) ? row : null;
},
link: async (input: LinkProjectRepositoryInput): Promise<ProjectRepository> => {
const connection = await this.connections.get({ orgId: input.orgId, id: input.connectionId });
const repository = await this.repositories.get({ orgId: input.orgId, id: input.repositoryId });
if (!connection || !repository || repository.installationId !== connection.installationId) {
throw new Error('Source-control connection or repository not found');
}
const existing = this.projectRepositoriesRows.find(
row => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId,
);
if (existing) return existing;
const now = new Date();
const created: ProjectRepository = {
id: randomUUID(),
connectionId: input.connectionId,
repositoryId: input.repositoryId,
createdByUserId: input.createdByUserId,
branch: input.branch ?? null,
sandboxProvider: input.sandboxProvider,
sandboxWorkdir: input.sandboxWorkdir,
setupCommand: input.setupCommand ?? null,
teardownCommand: input.teardownCommand ?? null,
createdAt: now,
updatedAt: now,View on GitHub (pinned to 75dd419e61)