stablyai/orca · error · Error

GitHub releases response page

Error message

GitHub releases response page ${page} for ${repo} was not an array

What it means

fetchReleases paginates /releases with per_page=100 and expects each page to be a JSON array. It throws when a page response is not an array, surfacing the page number and repo. A non-array page indicates the API returned an error object, a rate-limit document, or an unexpected shape rather than the release list, so continuing to paginate would be wrong.

Solutions

  1. Inspect the response body that preceded the throw (the message includes page and repo; capture the body separately to diagnose).
  2. Verify the token and rate-limit status, since some non-array 200s are rate-limit related.
  3. Confirm X-GitHub-Api-Version still matches the supported API version.
  4. Handle the non-array page in the caller instead of treating it as a hard failure.

Example fix

// before
if (!Array.isArray(pageReleases)) {
  throw new Error(`GitHub releases response page ${page} for ${repo} was not an array`)
}

// after — capture the body for diagnosis before failing
if (!Array.isArray(pageReleases)) {
  throw new Error(`GitHub releases response page ${page} for ${repo} was not an array; body=${JSON.stringify(pageReleases).slice(0, 300)}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

const sample = await githubJson(fetchImpl, urlPage1, token)
if (!Array.isArray(sample)) {
  throw new Error(`Unexpected releases shape for ${repo}: ${JSON.stringify(sample).slice(0,300)}`)
}

Type guard

function isReleaseArray(value: unknown): value is unknown[] {
  return Array.isArray(value)
}

Try / catch

try {
  releases = await fetchReleases(repo, token)
} catch (err) {
  if (/was not an array/.test(err.message)) {
    log.warn(`GitHub returned a non-array releases page for ${repo}; possible rate limit or proxy`)
  }
  throw err
}

Prevention

When it happens

Trigger: GitHub returns a 200 with a non-array body (rare, e.g. an API gateway error document or an abuse-rate-limit object); a proxy/interceptor rewrites the response; the endpoint contract changes.

Common situations: An enterprise/proxy returning an HTML or object error body with status 200; an API change after a GitHub API version bump; a rate-limit response that still carries 200.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/46ed7f27806fab80. Report an issue: GitHub.

Appendix: source

Thrown at config/scripts/latest-stable-release.mjs:63

}

export async function fetchReleases(repo, token, fetchImpl = fetch) {
  if (!repo) {
    throw new Error('repo is required')
  }
  if (!token) {
    throw new Error('token is required')
  }

  const releases = []
  for (let page = 1; ; page += 1) {
    const pageReleases = await githubJson(
      fetchImpl,
      `https://api.github.com/repos/${repo}/releases?per_page=100&page=${page}`,
      token
    )
    if (!Array.isArray(pageReleases)) {
      throw new Error(`GitHub releases response page ${page} for ${repo} was not an array`)
    }

    releases.push(...pageReleases)
    if (pageReleases.length < 100) {
      break
    }
  }

  return releases
}

async function main() {
  const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
  const repo = process.env.GITHUB_REPOSITORY || 'stablyai/orca'
  const releases = await fetchReleases(repo, token)
  process.stdout.write(latestStableDesktopReleaseTag(releases))
}

View on GitHub (pinned to 1136503c6a)