mastra-ai/mastra · error · Error

GitHub owner and repo may only contain letters, numbers, dot

Error message

GitHub owner and repo may only contain letters, numbers, dots, underscores, and dashes

What it means

After structural validation, parseGithubUrl checks the owner and repo (with a trailing '.git' stripped) against /^[A-Za-z0-9_.-]+$/. Characters outside that set — e.g. URL-encoded, Unicode, or shell metacharacters — are rejected to prevent path/shell injection when the SDK clones the repo and writes into the plugin directory.

Source

Thrown at mastracode/sdk/src/plugins/install.ts:248

  let url: URL;
  try {
    url = new URL(urlPart);
  } catch {
    throw new Error(`Invalid GitHub URL: ${specifier}`);
  }

  if (url.hostname !== 'github.com') {
    throw new Error('Only github.com plugin URLs are supported');
  }

  const [owner, rawRepo, ...rest] = url.pathname.split('/').filter(Boolean);
  if (!owner || !rawRepo || rest.length > 0) {
    throw new Error('GitHub plugin URL must be in the form https://github.com/owner/repo');
  }

  const repo = rawRepo.replace(/\.git$/, '');
  if (!/^[A-Za-z0-9_.-]+$/.test(owner) || !/^[A-Za-z0-9_.-]+$/.test(repo)) {
    throw new Error('GitHub owner and repo may only contain letters, numbers, dots, underscores, and dashes');
  }

  return {
    owner,
    repo,
    repoSpec: `${owner}/${repo}`,
    ...(ref ? { ref } : {}),
  };
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use the exact owner/repo names as they appear on github.com (letters, numbers, dots, underscores, dashes only).
  2. Remove URL encoding — write the literal ASCII name, not percent-encoded forms.
  3. Drop non-standard suffixes like '~branch' from the repo segment; use the '#ref' fragment for refs instead.

Example fix

// before
await installPlugin('https://github.com/acme/widgets%20pro');
// after
await installPlugin('https://github.com/acme/widgets-pro');
Defensive patterns

Strategy: validation

Validate before calling

const NAME_RE = /^[A-Za-z0-9_.-]+$/;
function hasValidOwnerRepo(specifier: string): boolean {
  try {
    const [owner, repo = ''] = new URL(specifier.split('#')[0]).pathname.split('/').filter(Boolean);
    return NAME_RE.test(owner) && NAME_RE.test(repo.replace(/\.git$/, ''));
  } catch {
    return false;
  }
}

Try / catch

try {
  await installPlugin(specifier);
} catch (error) {
  if (error instanceof Error && error.message.startsWith('GitHub owner and repo may only contain')) {
    throw new Error(`Owner/repo in "${specifier}" contain unsupported characters; use the literal GitHub name`);
  }
  throw error;
}

Prevention

When it happens

Trigger: Specifiers with percent-encoded or special characters in owner/repo, like 'https://github.com/own%65r/repo' resolving to odd names, 'https://github.com/owner/repo~branch', or names containing '+', '@', or spaces.

Common situations: Hand-editing the URL and introducing characters that are not valid in GitHub owner/repo names; pasting a URL from a system that URL-encoded the path; repo names with unusual suffixes.

Related errors


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