{"record":{"id":"f5488027127bd08e","repo":"stablyai/orca","slug":"repo-is-required-f54880","errorCode":null,"errorMessage":"repo is required","messagePattern":"repo is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/latest-stable-release.mjs","lineNumber":49,"sourceCode":"\nasync function githubJson(fetchImpl, url, token) {\n  const res = await fetchImpl(url, {\n    headers: {\n      Accept: 'application/vnd.github+json',\n      Authorization: `Bearer ${token}`,\n      'X-GitHub-Api-Version': API_VERSION\n    }\n  })\n  if (!res.ok) {\n    const body = await res.text().catch(() => '')\n    throw new Error(`GitHub request failed ${res.status} ${res.statusText}: ${body.slice(0, 300)}`)\n  }\n  return res.json()\n}\n\nexport async function fetchReleases(repo, token, fetchImpl = fetch) {\n  if (!repo) {\n    throw new Error('repo is required')\n  }\n  if (!token) {\n    throw new Error('token is required')\n  }\n\n  const releases = []\n  for (let page = 1; ; page += 1) {\n    const pageReleases = await githubJson(\n      fetchImpl,\n      `https://api.github.com/repos/${repo}/releases?per_page=100&page=${page}`,\n      token\n    )\n    if (!Array.isArray(pageReleases)) {\n      throw new Error(`GitHub releases response page ${page} for ${repo} was not an array`)\n    }\n\n    releases.push(...pageReleases)\n    if (pageReleases.length < 100) {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/latest-stable-release.mjs#L31-L67","documentation":"fetchReleases requires a non-empty repo slug (e.g. 'stablyai/orca') and throws 'repo is required' before issuing any request when it is falsy. This guards against building a malformed API URL and getting a confusing 404. The CLI entrypoint defaults repo to GITHUB_REPOSITORY or 'stablyai/orca'.","triggerScenarios":"Calling fetchReleases('', token) or fetchReleases(undefined, token); running main() with GITHUB_REPOSITORY unset would still fall through to the default, so a direct caller passing empty is the usual cause.","commonSituations":"A caller computing the repo slug from config that resolved to undefined; GITHUB_REPOSITORY intentionally cleared and no fallback passed.","solutions":["Pass a non-empty 'owner/name' repo slug.","Set GITHUB_REPOSITORY in the environment (the CLI default uses it).","Validate the slug upstream before calling fetchReleases."],"exampleFix":"// before\nawait fetchReleases('', token)\n\n// after\nconst repo = process.env.GITHUB_REPOSITORY || 'stablyai/orca'\nawait fetchReleases(repo, token)","handlingStrategy":"validation","validationCode":"const repo = process.env.GITHUB_REPOSITORY || 'stablyai/orca'\nif (!repo || !/^[^/\\s]+\\/[^/\\s]+$/.test(repo)) {\n  throw new Error(`Invalid or missing repo slug: ${String(repo)}`)\n}","typeGuard":"function isRepoSlug(value: unknown): value is string {\n  return typeof value === 'string' && /^[^/\\s]+\\/[^/\\s]+$/.test(value)\n}","tryCatchPattern":null,"preventionTips":["Default the repo to GITHUB_REPOSITORY with a known fallback before calling fetchReleases.","Validate the 'owner/name' shape upstream so the error is caught earlier with context."],"tags":["validation","github-api"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}