{"record":{"id":"00c0c384e129ce9b","repo":"affaan-m/ECC","slug":"announcements-discussion-category-is-required","errorCode":null,"errorMessage":"Announcements discussion category is required","messagePattern":"Announcements discussion category is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/discord/release-announce.mjs","lineNumber":74,"sourceCode":"    `query($owner:String!,$name:String!){repository(owner:$owner,name:$name){id discussionCategories(first:25){nodes{id name}}}}`,\n    { owner, name },\n  );\n  const repository = data.repository;\n  let cursor = null;\n  let existing = null;\n  for (let page = 0; page < 50 && !existing; page += 1) {\n    const pageData = await githubGraphql(\n      `query($owner:String!,$name:String!,$after:String){repository(owner:$owner,name:$name){discussions(first:100,after:$after,orderBy:{field:CREATED_AT,direction:DESC}){nodes{id title body url category{name}} pageInfo{hasNextPage endCursor}}}}`,\n      { owner, name, after: cursor },\n    );\n    const discussions = pageData.repository.discussions;\n    existing = findReleaseDiscussion(discussions.nodes, marker);\n    if (!discussions.pageInfo.hasNextPage) break;\n    cursor = discussions.pageInfo.endCursor;\n  }\n  if (existing) return existing;\n  const category = repository.discussionCategories.nodes.find(item => item.name === 'Announcements');\n  if (!category) throw new Error('Announcements discussion category is required');\n  const title = `${release.name || release.tag_name} release`;\n  const body = [marker, release.body || '', `Release: ${release.html_url}`].filter(Boolean).join('\\n\\n');\n  const created = await githubGraphql(\n    `mutation($repo:ID!,$cat:ID!,$title:String!,$body:String!){createDiscussion(input:{repositoryId:$repo,categoryId:$cat,title:$title,body:$body}){discussion{id title body url category{name}}}}`,\n    { repo: repository.id, cat: category.id, title, body },\n  );\n  return created.createDiscussion.discussion;\n}\n\nfunction discussionFromEnvironment() {\n  if (env.DISCUSSION_CATEGORY !== 'Announcements') throw new Error('discussion is not an Announcement');\n  return {\n    id: env.DISCUSSION_ID,\n    title: env.DISCUSSION_TITLE,\n    body: env.DISCUSSION_BODY,\n    url: env.DISCUSSION_URL,\n  };\n}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/discord/release-announce.mjs#L56-L92","documentation":"createOrFindReleaseDiscussion requires a discussion category literally named 'Announcements' in the target repository, and throws this error when no such category exists. GitHub discussion categories are repo-level settings the script cannot create via this path, so it fails fast instead of posting into a wrong category.","triggerScenarios":"The repository's discussionCategories.nodes contains no item with name === 'Announcements' after an existing release discussion was not found — the script is about to create a new discussion but cannot pick a category.","commonSituations":"Repo has discussions enabled but only default categories like 'General', 'Ideas', 'Q&A'; 'Announcements' category was renamed (e.g. 'Announcement'); discussions feature entirely disabled on the repo; running against a fork or fresh repo without the category set up.","solutions":["Create or rename a category to exactly 'Announcements' in the repo: Settings > Discussions, or gh api to edit discussion categories","Verify discussions are enabled on the repository","Check for case/whitespace differences between the repo's category name and the expected 'Announcements'","Consider making the required category name configurable via env var"],"exampleFix":"// before\nconst category = repository.discussionCategories.nodes.find(item => item.name === 'Announcements');\nif (!category) throw new Error('Announcements discussion category is required');\n// after\nconst wanted = env.DISCUSSION_CATEGORY || 'Announcements';\nconst category = repository.discussionCategories.nodes.find(item => item.name === wanted);\nif (!category) throw new Error(`Discussion category \"${wanted}\" is required; found: ${repository.discussionCategories.nodes.map(c => c.name).join(', ')}`);","handlingStrategy":"validation","validationCode":"// preflight: confirm the category exists\nconst cats = await fetch(`https://api.github.com/repos/${owner}/${repo}`, { headers: { Authorization: `Bearer ${token}` } });\n// GraphQL check:\n// query { repository(owner:\"o\",name:\"r\"){ discussionCategories(first:50){ nodes{ name } } } }\n// assert nodes includes 'Announcements' before invoking the announce script","typeGuard":"function hasAnnouncementsCategory(repository) {\n  return repository?.discussionCategories?.nodes?.some(c => c.name === 'Announcements') === true;\n}","tryCatchPattern":"try {\n  const discussion = await createOrFindReleaseDiscussion();\n} catch (err) {\n  if (err.message === 'Announcements discussion category is required') {\n    console.error('Repo discussion categories: enable Discussions and create an \"Announcements\" category');\n  }\n  throw err;\n}","preventionTips":["Create the 'Announcements' discussion category in repo Settings > Discussions as part of repo bootstrap","Document the required category in the workflow README/setup checklist","Compare category names case-insensitively in the script to tolerate renames","Store the category id in config as a fallback to name matching"],"tags":["github-api","configuration","discussions"],"backgroundTag":"missing-required-config","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"}