mastra-ai/mastra · error
GitHub capabilities require an owner/repository source.
Error message
GitHub capabilities require an owner/repository source.
What it means
Thrown by splitRepository when a sourceId does not contain an owner/repo pair separated by a slash (no slash, leading slash, or trailing slash). GitHub REST paths are built from owner and repo, so any capability call with a malformed source id fails here before a request is made.
Source
Thrown at mastracode/factory/src/integrations/platform/github/integration.ts:1442
}
function repositoryPath(sourceId: string, suffix: string): string {
const { owner, repo } = splitRepository(sourceId);
return `${API_PREFIX}/github/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${suffix}`;
}
function pullRequestPath(
input: { connection: IntegrationConnection; sourceId: string },
pullRequestId: string,
): string {
requireGithubConnection(input.connection);
return repositoryPath(input.sourceId, `pulls/${requirePositiveId(pullRequestId, 'pull request')}`);
}
function splitRepository(sourceId: string): { owner: string; repo: string } {
const slash = sourceId.indexOf('/');
if (slash <= 0 || slash === sourceId.length - 1) {
throw new Error('GitHub capabilities require an owner/repository source.');
}
return { owner: sourceId.slice(0, slash), repo: sourceId.slice(slash + 1) };
}
function parseIntakeIssue(sourceId: string, issue: GithubIssue): IntakeIssue {
return {
id: String(issue.number),
identifier: `#${issue.number}`,
title: issue.title,
url: issue.htmlUrl,
author: issue.user?.login ?? null,
state: issue.state,
stateType: issue.state,
priority: null,
assignee: issue.assignees[0] ?? null,
assignees: issue.assignees,
source: sourceId,
labels: issue.labels,View on GitHub (pinned to 75dd419e61)
Solutions
- Pass the full GitHub slug ('owner/repo') as sourceId
- Fix upstream source records so the stored slug matches GitHub's full_name
- Trim the value and re-check for stray leading/trailing slashes before calling
- Validate with a regex like /^[^/]+\/[^/]+$/ before invoking
Example fix
// before
await github.listPullRequests({ installationId, sourceIds: ['my-repo'] });
// after
await github.listPullRequests({ installationId, sourceIds: ['acme/my-repo'] }); Defensive patterns
Strategy: validation
Validate before calling
function isValidOwnerRepo(sourceId: string): boolean {
const slash = sourceId.indexOf('/');
return slash > 0 && slash < sourceId.length - 1;
}
if (!isValidOwnerRepo(sourceId)) throw new Error(`sourceId '${sourceId}' must be 'owner/repo'`); Type guard
function isGithubSlug(s: string): s is `${string}/${string}` {
const i = s.indexOf('/');
return i > 0 && i < s.length - 1;
} Try / catch
try {
await github.listPullRequests({ installationId, sourceIds: [sourceId] });
} catch (err) {
if (err instanceof Error && err.message.includes('owner/repository source')) {
sourceId = await resolveGithubSlug(sourceId); // map local id -> owner/repo
} else throw err;
} Prevention
- Store and pass GitHub full_name ('owner/repo') as sourceId everywhere
- Normalize/trim slugs at ingestion time
- Type sourceId as `${string}/${string}` in calling code to catch mistakes at compile time
- Add a fixture/contract test asserting sourceIds are slugs
When it happens
Trigger: Calling any GitHub capability (issues, pulls, comments, etc.) with a sourceIds[0] value like 'my-repo', '/my-repo', or 'owner/' — anything where sourceId.indexOf('/') is <= 0 or at the last character.
Common situations: Passing a repository name instead of its full slug; the platform storing a local repo id instead of the GitHub full_name; trailing whitespace or trailing slash from copy-paste; intake sync wrote a slugless source.
Related errors
- GitHub repository is invalid.
- GitHub installation id is invalid.
- GitHub pull requests require an owner/repository source.
- A review comment requires commitId, path, line, and side unl
- A multi-line review comment requires both startLine and star
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b4f04639d7c28895.
Report an issue: GitHub.