affaan-m/ECC · error · Error

Announcements discussion category is required

Error message

Announcements discussion category is required

What it means

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.

Solutions

  1. Create or rename a category to exactly 'Announcements' in the repo: Settings > Discussions, or gh api to edit discussion categories
  2. Verify discussions are enabled on the repository
  3. Check for case/whitespace differences between the repo's category name and the expected 'Announcements'
  4. Consider making the required category name configurable via env var

Example fix

// before
const category = repository.discussionCategories.nodes.find(item => item.name === 'Announcements');
if (!category) throw new Error('Announcements discussion category is required');
// after
const wanted = env.DISCUSSION_CATEGORY || 'Announcements';
const category = repository.discussionCategories.nodes.find(item => item.name === wanted);
if (!category) throw new Error(`Discussion category "${wanted}" is required; found: ${repository.discussionCategories.nodes.map(c => c.name).join(', ')}`);
Defensive patterns

Strategy: validation

Validate before calling

// preflight: confirm the category exists
const cats = await fetch(`https://api.github.com/repos/${owner}/${repo}`, { headers: { Authorization: `Bearer ${token}` } });
// GraphQL check:
// query { repository(owner:"o",name:"r"){ discussionCategories(first:50){ nodes{ name } } } }
// assert nodes includes 'Announcements' before invoking the announce script

Type guard

function hasAnnouncementsCategory(repository) {
  return repository?.discussionCategories?.nodes?.some(c => c.name === 'Announcements') === true;
}

Try / catch

try {
  const discussion = await createOrFindReleaseDiscussion();
} catch (err) {
  if (err.message === 'Announcements discussion category is required') {
    console.error('Repo discussion categories: enable Discussions and create an "Announcements" category');
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/00c0c384e129ce9b. Report an issue: GitHub.

Appendix: source

Thrown at scripts/discord/release-announce.mjs:74

    `query($owner:String!,$name:String!){repository(owner:$owner,name:$name){id discussionCategories(first:25){nodes{id name}}}}`,
    { owner, name },
  );
  const repository = data.repository;
  let cursor = null;
  let existing = null;
  for (let page = 0; page < 50 && !existing; page += 1) {
    const pageData = await githubGraphql(
      `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}}}}`,
      { owner, name, after: cursor },
    );
    const discussions = pageData.repository.discussions;
    existing = findReleaseDiscussion(discussions.nodes, marker);
    if (!discussions.pageInfo.hasNextPage) break;
    cursor = discussions.pageInfo.endCursor;
  }
  if (existing) return existing;
  const category = repository.discussionCategories.nodes.find(item => item.name === 'Announcements');
  if (!category) throw new Error('Announcements discussion category is required');
  const title = `${release.name || release.tag_name} release`;
  const body = [marker, release.body || '', `Release: ${release.html_url}`].filter(Boolean).join('\n\n');
  const created = await githubGraphql(
    `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}}}}`,
    { repo: repository.id, cat: category.id, title, body },
  );
  return created.createDiscussion.discussion;
}

function discussionFromEnvironment() {
  if (env.DISCUSSION_CATEGORY !== 'Announcements') throw new Error('discussion is not an Announcement');
  return {
    id: env.DISCUSSION_ID,
    title: env.DISCUSSION_TITLE,
    body: env.DISCUSSION_BODY,
    url: env.DISCUSSION_URL,
  };
}

View on GitHub (pinned to 8321021c54)