mastra-ai/mastra · error

GitHub repository is invalid.

Error message

GitHub repository is invalid.

What it means

verifyPullRequest splits the target repository's slug into owner and repo names before calling the GitHub API. If the slug does not split into both parts (empty owner or repo), this error is thrown. It guards against malformed repository slugs stored in the database.

Source

Thrown at mastracode/factory/src/integrations/github/session-subscriptions.ts:124

  }

  const projectRepository = await github.sourceControlStorage.projectRepositories.get({
    orgId,
    id: projectRepositoryId,
  });
  if (!projectRepository) throw new Error('Project repository not found for this organization.');
  const connection = await github.sourceControlStorage.connections.get({ orgId, id: projectRepository.connectionId });
  if (!connection) throw new Error('Source-control connection not found for this organization.');
  const repository = await github.sourceControlStorage.repositories.get({ orgId, id: projectRepository.repositoryId });
  if (!repository) throw new Error('Repository not found for this organization.');
  const installation = await github.sourceControlStorage.installations.get({ orgId, id: connection.installationId });
  if (!installation) throw new Error('Source-control installation not found for this organization.');
  return { context, projectRepository, connection, installation, repository, orgId, userId };
}

async function verifyPullRequest(target: SessionTarget, pullRequest: number, github: GithubIntegration) {
  const [owner, repo] = target.repository.slug.split('/');
  if (!owner || !repo) throw new Error('GitHub repository is invalid.');
  const octokit = github.getInstallationOctokit(Number(target.installation.externalId));
  const { data } = await octokit.pulls.get({ owner, repo, pull_number: pullRequest });
  if (String(data.base.repo.id) !== target.repository.externalId)
    throw new Error('Pull request repository does not match the active project repository.');
}

async function subscriptionInput(target: SessionTarget, pullRequestNumber: number) {
  return {
    orgId: target.orgId,
    installationExternalId: target.installation.externalId,
    projectRepositoryId: target.projectRepository.id,
    repositoryExternalId: target.repository.externalId,
    repositorySlug: target.repository.slug,
    changeRequestId: String(pullRequestNumber),
    sessionId: target.context.session.id,
    ownerId: target.context.session.ownerId,
    resourceId: target.connection.factoryProjectId,
    threadId: target.context.threadId!,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Fix the repository slug in storage to the canonical 'owner/repo' format
  2. Re-sync the repository from GitHub so the slug is recomputed correctly
  3. Validate slug format at repository ingestion time before persisting
Defensive patterns

Strategy: validation

Validate before calling

const [owner, repo] = slug.split('/');
if (!owner || !repo) throw new Error(`invalid repository slug: ${slug}`);

Type guard

function isWellFormedSlug(slug: string): boolean {
  const [owner, repo] = slug.split('/');
  return Boolean(owner && repo);
}

Prevention

When it happens

Trigger: target.repository.slug lacks the 'owner/name' format, e.g. empty string, 'owner/' or '/name', so destructuring yields an undefined segment.

Common situations: Corrupt or manually edited repository rows; import scripts writing slugs without an owner portion.

Related errors


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