stablyai/orca · error · Error

GitHub releases response for

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.

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.

Appendix: 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)