stablyai/orca · error

invalid response shape

Error message

invalid response shape

What it means

Thrown by getRestPRByNumber after parsing the stdout of `gh api repos/<owner>/<repo>/pulls/<n>`: the parsed JSON is not a plain object (it is null, an array, or a primitive). This is a defensive shape check before the value is cast to RestPullRequest. It indicates the API returned an unexpected body — typically an error envelope, an HTML error page mis-served as 200, or a gh CLI wrapper that emitted non-JSON.

Source

Thrown at src/main/github/client.ts:2997

    typeof base.ref === 'string' &&
    base.ref.trim().length > 0 &&
    (base.sha === undefined || isGitObjectId(base.sha))
  )
}

async function getRestPRByNumber(
  ownerRepo: GitHubApiRepository,
  number: number,
  ghOptions: ReturnType<typeof ghRepoExecOptions>,
  options: { requireUsableStackMetadata?: boolean } = {}
): Promise<PullRequestLookupData> {
  const { stdout } = await ghExecFileAsync(
    ['api', `repos/${ownerRepo.owner}/${ownerRepo.repo}/pulls/${number}`],
    { ...ghOptions, ...githubHostExecOptions(ownerRepo) }
  )
  const parsed = JSON.parse(stdout) as unknown
  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
    throw new Error('invalid response shape')
  }
  const restData = parsed as RestPullRequest
  const mapped = mapRestPullRequest(restData)
  if (
    options.requireUsableStackMetadata &&
    restData.stack !== undefined &&
    restData.stack !== null
  ) {
    // Why: GitHub omits stack for ordinary PRs; only unusable non-null metadata is unsafe.
    if (!isUsableRestStackMetadata(restData.stack) || !mapped.stack) {
      throw new Error('malformed stack')
    }
    if (!isGitObjectId(restData.head?.sha)) {
      throw new Error('missing head SHA')
    }
  }
  return mapped
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Reproduce with `gh api repos/<owner>/<repo>/pulls/<n>` in a terminal and inspect the raw output.
  2. If a proxy is injecting HTML, bypass it or add the GitHub host to the no-proxy list.
  3. Upgrade gh CLI to a current version to avoid wrapper noise in stdout.
  4. For GitHub Enterprise, confirm the server version supports the pulls REST shape.
Defensive patterns

Strategy: type-guard

Validate before calling

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v)
}

Type guard

function isRestPullRequestShape(v: unknown): v is Record<string, unknown> {
  return isPlainObject(v) && ('id' in v || 'number' in v || 'head' in v)
}

Try / catch

try {
  const pr = await getRestPRByNumber(ownerRepo, number, ghOptions)
} catch (err) {
  if ((err as Error).message === 'invalid response shape') {
    logRawGhApiOutput(ownerRepo, number) // capture the offending payload
    toast.error('GitHub returned an unexpected PR payload.')
  } else throw err
}

Prevention

When it happens

Trigger: GitHub returned an error envelope with 200 (rare proxy behavior); gh CLI printed a warning line before the JSON; a corporate proxy injected an HTML block page; the API response was truncated mid-stream; gh authenticated against a GitHub Enterprise Server version with a different response shape.

Common situations: Corporate MITM proxy returning HTML; gh CLI version mismatch emitting extra stdout; GitHub Enterprise Server older version; flaky network truncating the response body.

Related errors


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