mastra-ai/mastra · error
Version-control repository not found.
Error message
Version-control repository not found.
What it means
getRepositoryAccess resolves a repository by orgId and repositoryId from the source-control storage; if no repository record exists for that pair, it throws 'Version-control repository not found.' This is a runtime existence check (deliberately kept in execute logic, not schema validation) that also guards the follow-up installation lookup, since the repository record carries the installationId needed to resolve GitHub App installation access.
Source
Thrown at mastracode/factory/src/integrations/github/integration.ts:293
}),
registerRepositories: ({ orgId, installationId, repositories }) =>
Promise.all(
repositories.map(repository =>
this.sourceControlStorage.repositories.upsert({
orgId,
input: {
installationId,
externalId: repository.externalId,
slug: repository.slug,
defaultBranch: repository.defaultBranch,
providerMetadata: repository.metadata,
},
}),
),
),
getRepositoryAccess: async ({ orgId, repositoryId }) => {
const repository = await this.sourceControlStorage.repositories.get({ orgId, id: repositoryId });
if (!repository) throw new Error('Version-control repository not found.');
const installation = await this.sourceControlStorage.installations.get({
orgId,
id: repository.installationId,
});
if (!installation) throw new Error('Version-control installation not found.');
const installationId = Number.parseInt(installation.externalId, 10);
if (!Number.isSafeInteger(installationId)) throw new Error('GitHub installation id is invalid.');
return {
cloneUrl: `https://github.com/${repository.slug}.git`,
authorization: { scheme: 'bearer', token: await this.mintInstallationToken(installationId) },
};
},
listPullRequests: input => this.#listPullRequests(input),
getPullRequest: input => this.#getPullRequest(input),
createPullRequest: input => this.#createPullRequest(input),
updatePullRequest: input => this.#updatePullRequest(input),
closePullRequest: input => this.#closePullRequest(input),
mergePullRequest: input => this.#mergePullRequest(input),View on GitHub (pinned to 75dd419e61)
Solutions
- Verify the orgId/repositoryId pair exists: query sourceControlStorage.repositories.get({ orgId, id: repositoryId }) or list repositories for the org and confirm the id.
- Re-sync the org's repositories so deleted/renamed repos are refreshed, then retry with the current id.
- Use the internal repository record id, not the GitHub external id — the lookup is by the stored record's id field.
- Ensure the caller is using the correct orgId (the storage tenant key), not just any org the user belongs to.
- Handle the error upstream by returning a 404-style response to the requester instead of crashing.
Example fix
// before
await github.getRepositoryAccess({ orgId, repositoryId: githubRepoNumberId });
// after
const repos = await github.listRepositories({ orgId });
const repo = repos.find(r => r.externalId === String(githubRepoNumberId));
if (!repo) throw new NotFoundError('Repository not synced');
await github.getRepositoryAccess({ orgId, repositoryId: repo.id }); Defensive patterns
Strategy: try-catch
Validate before calling
const repo = await sourceControlStorage.repositories.get({ orgId, id: repositoryId });
if (!repo) {
throw new ObjectNotFoundError(`Repository ${repositoryId} not found in org ${orgId}; re-sync repositories first`);
} Type guard
function repoExists(repo, orgId, repositoryId) {
return repo != null && repo.orgId === orgId && repo.id === repositoryId;
} Try / catch
try {
await github.getRepositoryAccess({ orgId, repositoryId });
} catch (err) {
if (err.message === 'Version-control repository not found.') {
await github.syncRepositories({ orgId }); // refresh, then retry once
return github.getRepositoryAccess({ orgId, repositoryId });
}
throw err;
} Prevention
- Always resolve repositoryId via the internal record id, not GitHub's external id
- Re-sync repositories after upstream renames/deletes before resolving access
- Verify orgId matches the storage tenant for the requesting user
- Return 404-style responses to callers instead of letting the throw propagate
When it happens
Trigger: Calling getRepositoryAccess({ orgId, repositoryId }) where the repositories table has no row with that orgId/id — e.g. a stale repositoryId after the repo was deleted or re-synced, a wrong org, or a repository stored under a different orgId than the one passed.
Common situations: Referencing a repository id from another environment's database; repository removed by a sync/prune job while cached references remain; passing the GitHub repo's external numeric id instead of the internal repository record id; cross-tenant lookup where orgId doesn't match the stored row.
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
- Version-control installation not found.
- Project repository not found for this organization.
- Source-control connection not found for this organization.
- Repository not found for this organization.
- Source-control installation not found for this organization.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6865eca206cadc3b.
Report an issue: GitHub.