mastra-ai/mastra · error

GitHub triage comments require an owner/repository source.

Error message

GitHub triage comments require an owner/repository source.

What it means

upsertFactoryTriageComment requires input.repository to be a full 'owner/repo' identifier that splitRepoFullName can parse. When the repository string is empty, malformed, or not owner/repo shaped, the method refuses to proceed because it cannot address the GitHub REST API.

Source

Thrown at mastracode/factory/src/integrations/github/integration.ts:1278

        labels: (issue.labels ?? [])
          .map(label => (typeof label === 'string' ? label : label.name))
          .filter((name): name is string => Boolean(name)),
        ...(issue.user?.login ? { author: issue.user.login } : {}),
        createdAt: issue.created_at,
        updatedAt: issue.updated_at,
      };
    } catch {
      return undefined;
    }
  }

  /**
   * Session-scoped agent tools for token refresh and PR subscriptions in
   * sessions bound to a GitHub-backed project. Empty elsewhere.
   */
  async upsertFactoryTriageComment(input: GithubTriageCommentUpsertInput): Promise<GithubTriageCommentUpsertResult> {
    const parts = splitRepoFullName(input.repository);
    if (!parts) throw new Error('GitHub triage comments require an owner/repository source.');
    const octokit = this.getInstallationOctokit(input.installationId);
    const comments = [] as Array<{
      id: number;
      body?: string | null;
      user?: { login?: string } | null;
      html_url: string;
    }>;
    for (let page = 1; ; page += 1) {
      const response = await octokit.issues.listComments({
        ...parts,
        issue_number: input.issueNumber,
        per_page: 100,
        page,
      });
      comments.push(...response.data);
      if (response.data.length < 100) break;
    }
    const existing = comments

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass the full owner/repo slug, e.g. 'acme/widgets'.
  2. Derive the slug from the git remote URL by stripping the host and '.git'.
  3. Validate the repository string with a /^[^/]+\/[^/]+$/ check before calling.
  4. Check where the repository value is populated in your project/config wiring for truncation.

Example fix

// before
await gh.upsertFactoryTriageComment({ repository: 'widgets', ... });
// after
await gh.upsertFactoryTriageComment({ repository: 'acme/widgets', ... });
Defensive patterns

Strategy: validation

Validate before calling

const GITHUB_SLUG_RE = /^[^/]+\/[^/]+$/;
if (!GITHUB_SLUG_RE.test(input.repository)) throw new Error(`repository must be owner/repo, got: ${input.repository}`);

Type guard

function isRepoSlug(v: unknown): v is string {
  return typeof v === 'string' && /^[^/]+\/[^/]+$/.test(v);
}

Try / catch

try {
  await gh.upsertFactoryTriageComment({ repository: repo, ...input });
} catch (e) {
  if ((e as Error).message.includes('owner/repository')) throw new Error(`Invalid repository slug: ${repo}`);
  throw e;
}

Prevention

When it happens

Trigger: Calling upsertFactoryTriageComment with input.repository = '' , 'my-repo' (no owner), 'owner/repo/extra', or a URL instead of the owner/repo slug.

Common situations: Project source configured with only a repo name; parsing a git remote URL into the wrong variable; pulling repository name from a webhook payload field that uses a full name vs slug inconsistently.

Related errors


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