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
- Confirm the response came from api.github.com and was not intercepted (check the body slice from a reproduced request).
- If a proxy is in play, bypass it for api.github.com or fix the stub to return an array.
- 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
- If behind a proxy, bypass it for api.github.com so the array contract holds.
- When stubbing fetchImpl in tests, always return an array of release objects.
- Pin X-GitHub-Api-Version and re-verify the contract when upgrading the API version.
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
- GitHub request failed ${res.status} ${res.statusText}: ${bod
- repo is required
- token is required
- GitHub ${bucket} rate limit is low; retry after ${new Date(g
- invalid response shape
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/7ef011f7a536ae4c.
Report an issue: GitHub.