{"record":{"id":"053e39b8910f5e8c","repo":"affaan-m/ECC","slug":"discussion-receipt-lookup-exceeded-page-budget","errorCode":null,"errorMessage":"discussion receipt lookup exceeded page budget","messagePattern":"discussion receipt lookup exceeded page budget","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/discord/release-announce.mjs","lineNumber":119,"sourceCode":"  if (discussion.category?.name !== 'Announcements') throw new Error('discussion is not an Announcement');\n  return { id: discussion.node_id, title: discussion.title, body: discussion.body, url: discussion.html_url };\n}\n\nasync function findReceiptComment(discussionId, marker) {\n  let cursor = null;\n  for (let page = 0; page < 50; page += 1) {\n    const data = await githubGraphql(\n      `query($id:ID!,$after:String){node(id:$id){... on Discussion{comments(first:100,after:$after){nodes{id body author{login}} pageInfo{hasNextPage endCursor}}}}}`,\n      { id: discussionId, after: cursor },\n    );\n    const comments = data.node?.comments;\n    if (!comments) throw new Error('discussion receipt lookup failed');\n    const receipt = findDiscussionReceipt(comments.nodes, marker);\n    if (receipt) return receipt;\n    if (!comments.pageInfo.hasNextPage) return null;\n    cursor = comments.pageInfo.endCursor;\n  }\n  throw new Error('discussion receipt lookup exceeded page budget');\n}\n\nasync function addReceiptComment(discussionId, body) {\n  const data = await githubGraphql(\n    `mutation($id:ID!,$body:String!){addDiscussionComment(input:{discussionId:$id,body:$body}){comment{id}}}`,\n    { id: discussionId, body },\n  );\n  return data.addDiscussionComment.comment.id;\n}\n\nasync function deleteReceiptComment(commentId) {\n  await githubGraphql(\n    `mutation($id:ID!){deleteDiscussionComment(input:{id:$id}){clientMutationId}}`,\n    { id: commentId },\n  );\n}\n\nasync function discord(method, path, body) {","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/discord/release-announce.mjs#L101-L137","documentation":"findReceiptComment caps pagination at 50 pages of 100 comments (5000 comments). If the marker receipt comment has not been found after exhausting that budget, it throws instead of looping forever on a runaway or extremely large discussion.","triggerScenarios":"A discussion with more than 5000 comments where the receipt was never posted (or was posted beyond the page budget), or a pagination bug causing endCursor to never advance so hasNextPage stays true.","commonSituations":"Very high-traffic announcement discussions accumulating thousands of comments; receipt never actually created because a previous run crashed after creating the discussion but before commenting; GraphQL cursor reuse causing repeated pages.","solutions":["Increase the page budget (e.g. `for (let page = 0; page < 200; ...)`) if discussions legitimately exceed 5000 comments","Verify the receipt is actually posted by running addReceiptComment once and checking for duplicate-delivery logic elsewhere","Confirm pagination advances: log endCursor each iteration to detect a stuck cursor","Search comments server-side is not supported; consider storing receipts as a single pinned comment checked first"],"exampleFix":"// before\nfor (let page = 0; page < 50; page += 1) {\n// after\nconst MAX_PAGES = Number(env.RECEIPT_MAX_PAGES || 50);\nfor (let page = 0; page < MAX_PAGES; page += 1) {","handlingStrategy":"try-catch","validationCode":"// sanity-check comment count is within the budget\nconst count = await githubGraphql('query($id:ID!){node(id:$id){... on Discussion{comments(first:1){totalCount}}}}', { id: discussionId });\nconst total = count.node?.comments?.totalCount ?? 0;\nif (total > 5000) throw new Error(`Discussion has ${total} comments, exceeds 50x100 page budget`);","typeGuard":null,"tryCatchPattern":"try {\n  const receipt = await findReceiptComment(discussionId, marker);\n} catch (err) {\n  if (err.message === 'discussion receipt lookup exceeded page budget') {\n    console.error('Over 5000 comments; raise the page budget or use a dedicated/pinned receipt discussion');\n  }\n  throw err;\n}","preventionTips":["Keep announcement discussions lean; use a dedicated discussion per release for receipts","Make the page budget configurable rather than hardcoded at 50","Log cursors per page to detect pagination that never advances","Check receipt existence early via totalCount before paging"],"tags":["pagination","graphql","discussions"],"backgroundTag":"value-out-of-range","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}