{"record":{"id":"aca200b9b726b09b","repo":"stablyai/orca","slug":"malformed-stack","errorCode":null,"errorMessage":"malformed stack","messagePattern":"malformed stack","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/github/client.ts","lineNumber":3008,"sourceCode":"): Promise<PullRequestLookupData> {\n  const { stdout } = await ghExecFileAsync(\n    ['api', `repos/${ownerRepo.owner}/${ownerRepo.repo}/pulls/${number}`],\n    { ...ghOptions, ...githubHostExecOptions(ownerRepo) }\n  )\n  const parsed = JSON.parse(stdout) as unknown\n  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n    throw new Error('invalid response shape')\n  }\n  const restData = parsed as RestPullRequest\n  const mapped = mapRestPullRequest(restData)\n  if (\n    options.requireUsableStackMetadata &&\n    restData.stack !== undefined &&\n    restData.stack !== null\n  ) {\n    // Why: GitHub omits stack for ordinary PRs; only unusable non-null metadata is unsafe.\n    if (!isUsableRestStackMetadata(restData.stack) || !mapped.stack) {\n      throw new Error('malformed stack')\n    }\n    if (!isGitObjectId(restData.head?.sha)) {\n      throw new Error('missing head SHA')\n    }\n  }\n  return mapped\n}\n\nfunction prunePRStackSummaryCache(now = Date.now()): void {\n  for (const [key, cached] of prStackSummaryCache) {\n    if (cached.expiresAt <= now) {\n      prStackSummaryCache.delete(key)\n    }\n  }\n  while (prStackSummaryCache.size > PR_STACK_SUMMARY_CACHE_MAX_ENTRIES) {\n    const oldestKey = prStackSummaryCache.keys().next().value\n    if (oldestKey === undefined) {\n      return","sourceCodeStart":2990,"sourceCodeEnd":3026,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/github/client.ts#L2990-L3026","documentation":"Thrown by getRestPRByNumber when requireUsableStackMetadata is set, restData.stack is present and non-null, but isUsableRestStackMetadata rejects it OR mapRestPullRequest did not produce a stack. GitHub omits the stack field for ordinary PRs (which is fine — that path is skipped); only a non-null but unusable value triggers this. It guards against partial or malformed stack metadata that would render an inconsistent PR stack view.","triggerScenarios":"GitHub returns a stack object missing required child entries; the stack payload references PR numbers that didn't map; a beta stack feature returned a shape the mapper doesn't yet understand; the gh CLI or GitHub Enterprise served a partially-serialized stack.","commonSituations":"GitHub rolls out a stack-format change; a stacked-PR tool (Graphite, gh-stack) writes metadata in a non-standard shape; Enterprise Server lags behind on stack API fields.","solutions":["Inspect the raw `stack` field from `gh api repos/<owner>/<repo>/pulls/<n>` and compare against isUsableRestStackMetadata's requirements.","If the shape is genuinely new, file an issue — the mapper may need to recognize the new format.","As a workaround, calls without requireUsableStackMetadata will tolerate the field; use that path for display-only contexts."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { isUsableRestStackMetadata } from './stack-metadata'\nfunction stackIsUsable(stack: unknown): boolean {\n  return stack == null || isUsableRestStackMetadata(stack)\n}","typeGuard":"function isUsableRestStackMetadataShape(stack: unknown): boolean {\n  return typeof stack === 'object' && stack !== null &&\n    Array.isArray((stack as any).entries) && (stack as any).entries.length > 0\n}","tryCatchPattern":"try {\n  const pr = await getRestPRByNumber(ownerRepo, number, ghOptions, { requireUsableStackMetadata: true })\n} catch (err) {\n  if ((err as Error).message === 'malformed stack') {\n    // fall back to non-stack-aware lookup for display only\n    return getRestPRByNumber(ownerRepo, number, ghOptions)\n  }\n  throw err\n}","preventionTips":["For display-only contexts, call without requireUsableStackMetadata to tolerate partial stack data.","Track GitHub stack-format changes and update isUsableRestStackMetadata promptly.","Log the raw stack field when this fires so new shapes are caught early."],"tags":["github","api","stacked-prs","metadata","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}