{"record":{"id":"42187cf70b8bd50b","repo":"affaan-m/ECC","slug":"discussion-number-is-invalid","errorCode":null,"errorMessage":"discussion number is invalid","messagePattern":"discussion number is invalid","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/discord/release-announce.mjs","lineNumber":95,"sourceCode":"  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}\n\nasync function discussionFromGitHub() {\n  if (!/^\\d+$/.test(env.DISCUSSION_NUMBER || '')) throw new Error('discussion number is invalid');\n  const response = await request(`https://api.github.com/repos/${env.GITHUB_REPOSITORY}/discussions/${env.DISCUSSION_NUMBER}`, {\n    headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}`, Accept: 'application/vnd.github+json' },\n  });\n  if (!response.ok) throw new Error(`discussion lookup failed (${response.status})`);\n  const discussion = await response.json();\n  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');","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/discord/release-announce.mjs#L77-L113","documentation":"discussionFromGitHub throws this before making any network call when DISCUSSION_NUMBER is not a string of digits. The regex /^\\d+$/ guards the REST URL construction, since a non-numeric number would produce a malformed endpoint and a confusing 404/400 from GitHub.","triggerScenarios":"DISCUSSION_NUMBER env var is empty, unset, contains non-digit characters (e.g. a full URL like https://github.com/owner/repo/discussions/12, a '#12' reference, or trailing whitespace).","commonSituations":"Workflow passes the discussion URL instead of its number; value pasted with a leading '#' or spaces; DISCUSSION_NUMBER not exported in the job step; typo setting it to the issue number of a different entity.","solutions":["Set DISCUSSION_NUMBER to the bare numeric discussion id (e.g. 12)","Strip a leading '#' and extract the number if you only have a URL: DISCUSSION_NUMBER=$(basename \"$DISCUSSION_URL\")","Confirm the env var is exported and reachable inside the script's process","Echo the value in CI to see exactly what the script receives"],"exampleFix":"// before\nif (!/^\\d+$/.test(env.DISCUSSION_NUMBER || '')) throw new Error('discussion number is invalid');\n// after\nconst rawNumber = (env.DISCUSSION_NUMBER || '').trim().replace(/^#/, '');\nif (!/^\\d+$/.test(rawNumber)) throw new Error(`discussion number is invalid: \"${env.DISCUSSION_NUMBER}\"`);","handlingStrategy":"validation","validationCode":"const raw = (process.env.DISCUSSION_NUMBER || '').trim().replace(/^#/, '');\nif (!/^\\d+$/.test(raw)) throw new Error(`DISCUSSION_NUMBER must be numeric, got: ${process.env.DISCUSSION_NUMBER}`);","typeGuard":"function isValidDiscussionNumber(v) {\n  return typeof v === 'string' && /^\\d+$/.test(v.trim());\n}","tryCatchPattern":"try {\n  const discussion = await discussionFromGitHub();\n} catch (err) {\n  if (err.message === 'discussion number is invalid') {\n    console.error(`DISCUSSION_NUMBER=\"${process.env.DISCUSSION_NUMBER}\" — pass the bare numeric id, not a URL`);\n  }\n  throw err;\n}","preventionTips":["Pass the plain numeric discussion number in CI (extract from URL via basename if needed)","Never paste full discussion URLs or '#12' style refs into DISCUSSION_NUMBER","Echo the env value in the workflow step for debugging","Add inline normalization (trim, strip leading '#') before the regex"],"tags":["validation","environment","github-api"],"backgroundTag":"invalid-argument-format","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"}