{"record":{"id":"2de37436c756e263","repo":"stablyai/orca","slug":"github-returned-an-invalid-stack-response","errorCode":null,"errorMessage":"GitHub returned an invalid stack response.","messagePattern":"GitHub returned an invalid stack response\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/github/stacked-pr-creation.ts","lineNumber":289,"sourceCode":"\n    const parentStack = parentStacks[0]\n    const endpoint = parentStack\n      ? `repos/${args.repository.owner}/${args.repository.repo}/stacks/${parentStack.number}/add`\n      : `repos/${args.repository.owner}/${args.repository.repo}/stacks`\n    const pullRequests = parentStack\n      ? [args.currentReview.number]\n      : [args.parentReview.number, args.currentReview.number]\n    const command = ['api', '-X', 'POST', endpoint]\n    for (const pullRequest of pullRequests) {\n      command.push('-F', `pull_requests[]=${pullRequest}`)\n    }\n    const { stdout } = await ghExecFileAsync(command, {\n      ...ghOptions(args.repoPath, args.repository, args.connectionId, options),\n      idempotent: false\n    })\n    const stackNumber = Number((JSON.parse(stdout) as { number?: unknown }).number)\n    if (!Number.isInteger(stackNumber) || stackNumber <= 0) {\n      throw new Error('GitHub returned an invalid stack response.')\n    }\n    return {\n      ok: true,\n      ...args.currentReview,\n      stackNumber,\n      parentReview: args.parentReview\n    }\n  } catch (error) {\n    console.warn('GitHub stack registration failed:', error)\n    return {\n      ok: false,\n      code: isStacksUnavailableError(error) ? 'validation' : 'unknown',\n      error: isStacksUnavailableError(error)\n        ? 'The pull request was created, but GitHub stacks are not available for this repository.'\n        : 'The pull request was created, but GitHub could not add it to the stack. Retry to finish stack registration.',\n      createdReview: args.currentReview\n    }\n  } finally {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/github/stacked-pr-creation.ts#L271-L307","documentation":"Thrown after a successful `gh api -X POST .../stacks` call when the JSON body's `number` field is missing, not an integer, or <= 0. The GitHub Stacks API (a preview/early feature) returned a 2xx envelope whose shape does not match the expected `{ number }` contract, so the stack registration result cannot be trusted. The surrounding try/catch downgrades this to a non-fatal `{ ok: false }` with code 'unknown'.","triggerScenarios":"POSTing to `repos/:owner/:repo/stacks` or `.../stacks/:n/add` against a GitHub tier or version where the Stacks REST endpoint exists but returns a different schema (e.g. wraps the number under `stack.number`, returns `null`, or returns an empty object on a soft failure). Also seen when the endpoint is reachable through a GitHub Enterprise proxy that rewrites the body.","commonSituations":"GitHub Stacks is a preview feature not enabled on the repository/organization; GitHub changed the preview API schema between versions; gh CLI is authenticated to a different account that can read but not write stacks; the repository is on GitHub App auth lacking the stacks scope.","solutions":["Confirm GitHub Stacks is enabled for the repository/organization (preview feature flag) via the GitHub UI or `gh api repos/:owner/:repo/stacks`.","Upgrade the gh CLI to a version matching the Stacks preview contract, then retry — the catch block returns code 'unknown' prompting a retry.","Inspect the raw `stdout` from the gh call (add temporary logging) to see the actual returned shape and adjust the parser if the field moved (e.g. `stack.number`).","If stacks are unavailable, treat the result as terminal: the PR was still created (createdReview is returned), so no re-create is needed."],"exampleFix":"// before\nconst stackNumber = Number((JSON.parse(stdout) as { number?: unknown }).number)\nif (!Number.isInteger(stackNumber) || stackNumber <= 0) {\n  throw new Error('GitHub returned an invalid stack response.')\n}\n// after — tolerate nested or alternate envelope shapes\nconst parsed = JSON.parse(stdout) as { number?: unknown; stack?: { number?: unknown } }\nconst stackNumber = Number(parsed.number ?? parsed.stack?.number)\nif (!Number.isInteger(stackNumber) || stackNumber <= 0) {\n  throw new Error(`GitHub returned an invalid stack response: ${stdout.slice(0, 200)}`)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isStackResponse(body: unknown): body is { number: number } {\n  return typeof body === 'object' && body !== null\n    && Number.isInteger((body as { number?: unknown }).number)\n    && (body as { number: number }).number > 0\n}","tryCatchPattern":"// The surrounding code already try/catches and returns { ok: false, code: 'unknown' }.\n// Callers should branch on result.ok === false and retry on code 'unknown':\nif (!result.ok && result.code === 'unknown') {\n  await retryStackRegistration(args) // limited retries, then surface to user\n}","preventionTips":["Confirm the Stacks preview is enabled on the repo before offering stack creation in the UI.","Keep gh CLI version aligned with the GitHub Stacks API contract.","Treat stack registration as best-effort: the PR is created regardless; surface a non-blocking retry to the user."],"tags":["github","api","stacks","schema","gh-cli"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}