stablyai/orca · error · Error

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

Error message

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

What it means

Thrown by fetchReleases in config/scripts/publish-complete-draft-releases.mjs when the GitHub `/repos/{repo}/releases` endpoint returns an HTTP-OK response whose JSON body is not an Array. The releases endpoint is contractually an array, so a non-array (an error object, a single release object, or a proxy-intercepted shape) signals a corrupted or redirected response that the rest of the pipeline cannot filter or sort.

Source

Thrown at config/scripts/publish-complete-draft-releases.mjs:71

      'X-GitHub-Api-Version': API_VERSION,
      ...options.headers
    }
  })
  if (!res.ok) {
    const body = await res.text().catch(() => '')
    throw new Error(`GitHub request failed ${res.status} ${res.statusText}: ${body.slice(0, 300)}`)
  }
  return res.json()
}

async function fetchReleases(repo, token, fetchImpl) {
  const releases = await githubJson(
    fetchImpl,
    `https://api.github.com/repos/${repo}/releases?per_page=100`,
    token
  )
  if (!Array.isArray(releases)) {
    throw new Error(`GitHub releases response for ${repo} was not an array`)
  }
  return releases
}

export async function publishCompleteDraftReleases({
  repo,
  token,
  fetchImpl = fetch,
  verifyReleaseAssets = verifyRequiredReleaseAssets,
  isDraftBuiltFromCurrentRef = ({ tag }) => isTagBuiltFromCurrentRef(tag),
  log = console.log
}) {
  if (!repo) {
    throw new Error('repo is required')
  }
  if (!token) {
    throw new Error('token is required')
  }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Confirm the response came from api.github.com and was not intercepted (check the body slice from a reproduced request).
  2. If a proxy is in play, bypass it for api.github.com or fix the stub to return an array.
  3. Verify X-GitHub-Api-Version 2022-11-28 still matches the live API contract for the releases listing.

Example fix

// before
const releases = await githubJson(fetchImpl, url, token)
// releases consumed directly as an array

// after
const releases = await githubJson(fetchImpl, url, token)
if (!Array.isArray(releases)) {
  throw new Error(`Unexpected releases payload for ${repo}: ${JSON.stringify(releases).slice(0, 200)}`)
}
Defensive patterns

Strategy: validation

Validate before calling

const releases = await githubJson(fetchImpl, url, token)
if (!Array.isArray(releases)) {
  throw new Error(`Unexpected releases payload for ${repo}: ${JSON.stringify(releases).slice(0, 200)}`)
}
return releases

Type guard

function isReleaseArray(res) {
  return Array.isArray(res) && res.every((r) => r && typeof r.tag_name === 'string')
}

Prevention

When it happens

Trigger: GitHub returns 200 with a non-array body — rare but possible behind a corporate proxy that swaps in an HTML/error JSON object, or if the API contract changes and a future endpoint returns a paginated envelope object. The check at line 70-71 fires immediately after githubJson succeeds.

Common situations: A transparent proxy or npm-registry mirror rewrites the GitHub response, a test fetchImpl stub returns a hand-crafted object instead of an array, or an API-version mismatch (the script pins X-GitHub-Api-Version to 2022-11-28) returns a different envelope on a future API revision.

Related errors


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