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
- Set SITE_URL to override entirely: SITE_URL=https://example.com (takes precedence over GITHUB_REPOSITORY).
- Ensure GITHUB_REPOSITORY is 'owner/repo' — the standard GitHub Actions value, which always splits cleanly.
- 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
- Set SITE_URL in any non-standard Actions environment to bypass GITHUB_REPOSITORY parsing.
- Unset GITHUB_REPOSITORY for local dev so the localhost fallback applies.
- Validate env at workflow start so a malformed GITHUB_REPOSITORY fails early and clearly.
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
- All selected tool(s) are suspended: ${suspendedIdes.join(',
- Platform codes configuration not found at: ${PLATFORM_CODES_
- [rehype-markdown-links] Could not detect content directory f
- Obsolete implementation terminology found in deployable docu
- llms.txt must describe Build as canonical for both direct in
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/84c861d3c34c234a.
Report an issue: GitHub.