bmad-code-org/BMAD-METHOD · error · Error

Invalid GITHUB_REPOSITORY format: "${process.env.GITHUB_REPO

Error message

Invalid GITHUB_REPOSITORY format: "${process.env.GITHUB_REPOSITORY}". Expected "owner/repo".

What it means

Thrown by getSiteUrl when GITHUB_REPOSITORY is set but doesn't split into exactly two non-empty owner/repo parts. The function derives the GitHub Pages URL as https://{owner}.github.io/{repo}; a malformed value can't yield a valid URL so it throws rather than emit a broken base URL.

Source

Thrown at website/src/lib/site-url.mjs:17

/**
 * Resolve the site's base URL using cascading environment defaults.
 *
 * Preference order: use SITE_URL if set; otherwise derive a GitHub Pages URL from GITHUB_REPOSITORY; otherwise use the local development URL.
 * @returns {string} The resolved site URL (SITE_URL override, or `https://{owner}.github.io/{repo}`, or `http://localhost:3000`).
 */
export function getSiteUrl() {
  // Explicit override (works in both local and GitHub Actions)
  if (process.env.SITE_URL) {
    return process.env.SITE_URL.replace(/\/+$/, '');
  }

  // GitHub Actions: compute from repository context
  if (process.env.GITHUB_REPOSITORY) {
    const parts = process.env.GITHUB_REPOSITORY.split('/');
    if (parts.length !== 2 || !parts[0] || !parts[1]) {
      throw new Error(`Invalid GITHUB_REPOSITORY format: "${process.env.GITHUB_REPOSITORY}". Expected "owner/repo".`);
    }
    const [owner, repo] = parts;
    return `https://${owner}.github.io/${repo}`;
  }

  // Local development: use dev server
  return 'http://localhost:3000';
}

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Set SITE_URL to override entirely: SITE_URL=https://example.com (takes precedence over GITHUB_REPOSITORY).
  2. Ensure GITHUB_REPOSITORY is 'owner/repo' — the standard GitHub Actions value, which always splits cleanly.
  3. Unset GITHUB_REPOSITORY locally if you want the http://localhost:3000 fallback.

Example fix

# before (workflow)
#   env:
#     GITHUB_REPOSITORY: 'myrepo'        # missing owner
#
# after
#   env:
#     SITE_URL: https://example.com      # explicit override
#   # or rely on the default $GITHUB_REPOSITORY = owner/repo
Defensive patterns

Strategy: validation

Validate before calling

function isValidGitHubRepo(env) {
  if (!env.GITHUB_REPOSITORY) return true; // absent is fine
  const parts = env.GITHUB_REPOSITORY.split('/');
  return parts.length === 2 && !!parts[0] && !!parts[1];
}
if (!isValidGitHubRepo(process.env)) {
  if (!process.env.SITE_URL) {
    console.error('Set SITE_URL or fix GITHUB_REPOSITORY to owner/repo.');
    process.exit(1);
  }
}

Type guard

function isValidGitHubRepo(env) {
  if (!env.GITHUB_REPOSITORY) return true;
  const parts = env.GITHUB_REPOSITORY.split('/');
  return parts.length === 2 && !!parts[0] && !!parts[1];
}

Try / catch

try {
  siteUrl = getSiteUrl();
} catch (e) {
  if (/Invalid GITHUB_REPOSITORY format/.test(e.message)) {
    siteUrl = process.env.SITE_URL || 'http://localhost:3000';
  } else { throw e; }
}

Prevention

When it happens

Trigger: In GitHub Actions with a malformed GITHUB_REPOSITORY (e.g. '/repo', 'owner/', 'owner/repo/extra', or just 'repo'); locally with GITHUB_REPOSITORY manually set to a bad value.

Common situations: Manually setting GITHUB_REPOSITORY incorrectly in a workflow; a fork/mirror or custom runner that populates it oddly; testing locally with a leftover env var.

Related errors


AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13). Data as JSON: /api/errors/84c861d3c34c234a. Report an issue: GitHub.