{"record":{"id":"84c861d3c34c234a","repo":"bmad-code-org/BMAD-METHOD","slug":"invalid-github-repository-format-process-env-g","errorCode":null,"errorMessage":"Invalid GITHUB_REPOSITORY format: \"${process.env.GITHUB_REPOSITORY}\". Expected \"owner/repo\".","messagePattern":"Invalid GITHUB_REPOSITORY format: \"(.+?)\"\\. Expected \"owner/repo\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"website/src/lib/site-url.mjs","lineNumber":17,"sourceCode":"/**\n * Resolve the site's base URL using cascading environment defaults.\n *\n * Preference order: use SITE_URL if set; otherwise derive a GitHub Pages URL from GITHUB_REPOSITORY; otherwise use the local development URL.\n * @returns {string} The resolved site URL (SITE_URL override, or `https://{owner}.github.io/{repo}`, or `http://localhost:3000`).\n */\nexport function getSiteUrl() {\n  // Explicit override (works in both local and GitHub Actions)\n  if (process.env.SITE_URL) {\n    return process.env.SITE_URL.replace(/\\/+$/, '');\n  }\n\n  // GitHub Actions: compute from repository context\n  if (process.env.GITHUB_REPOSITORY) {\n    const parts = process.env.GITHUB_REPOSITORY.split('/');\n    if (parts.length !== 2 || !parts[0] || !parts[1]) {\n      throw new Error(`Invalid GITHUB_REPOSITORY format: \"${process.env.GITHUB_REPOSITORY}\". Expected \"owner/repo\".`);\n    }\n    const [owner, repo] = parts;\n    return `https://${owner}.github.io/${repo}`;\n  }\n\n  // Local development: use dev server\n  return 'http://localhost:3000';\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/website/src/lib/site-url.mjs#L1-L26","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (workflow)\n#   env:\n#     GITHUB_REPOSITORY: 'myrepo'        # missing owner\n#\n# after\n#   env:\n#     SITE_URL: https://example.com      # explicit override\n#   # or rely on the default $GITHUB_REPOSITORY = owner/repo","handlingStrategy":"validation","validationCode":"function isValidGitHubRepo(env) {\n  if (!env.GITHUB_REPOSITORY) return true; // absent is fine\n  const parts = env.GITHUB_REPOSITORY.split('/');\n  return parts.length === 2 && !!parts[0] && !!parts[1];\n}\nif (!isValidGitHubRepo(process.env)) {\n  if (!process.env.SITE_URL) {\n    console.error('Set SITE_URL or fix GITHUB_REPOSITORY to owner/repo.');\n    process.exit(1);\n  }\n}","typeGuard":"function isValidGitHubRepo(env) {\n  if (!env.GITHUB_REPOSITORY) return true;\n  const parts = env.GITHUB_REPOSITORY.split('/');\n  return parts.length === 2 && !!parts[0] && !!parts[1];\n}","tryCatchPattern":"try {\n  siteUrl = getSiteUrl();\n} catch (e) {\n  if (/Invalid GITHUB_REPOSITORY format/.test(e.message)) {\n    siteUrl = process.env.SITE_URL || 'http://localhost:3000';\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["website","config","github-actions","env","site-url"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}