{"record":{"id":"6042b1ec305363c5","repo":"affaan-m/ECC","slug":"discord-announcement-credentials-are-missing-or-in","errorCode":null,"errorMessage":"Discord announcement credentials are missing or invalid","messagePattern":"Discord announcement credentials are missing or invalid","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/discord/release-announce.mjs","lineNumber":183,"sourceCode":"    const response = await request(webhookUrl, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(payload),\n    });\n    if (!response.ok) {\n      await deleteReceiptComment(claimId);\n      throw new Error(`Discord webhook request failed (${response.status})`);\n    }\n    const message = await response.json();\n    await addReceiptComment(discussion.id, `${marker}\\n\\nDiscord delivery: complete (message ${message.id}).`);\n    await deleteReceiptComment(claimId).catch(() => {\n      console.warn('announcement delivered; pending receipt cleanup requires attention');\n    });\n    console.log('announcement delivered by channel webhook');\n    return;\n  }\n  if (!env.DISCORD_BOT_TOKEN || !/^\\d{10,25}$/.test(env.DISCORD_ANNOUNCE_CHANNEL_ID || '')) {\n    throw new Error('Discord announcement credentials are missing or invalid');\n  }\n  const recent = await discord('GET', `/channels/${env.DISCORD_ANNOUNCE_CHANNEL_ID}/messages?limit=100`);\n  const receipt = findDiscordReceipt(recent, key);\n  if (receipt) {\n    await discord('PUT', `/channels/${env.DISCORD_ANNOUNCE_CHANNEL_ID}/pins/${receipt.id}`);\n    console.log('announcement already delivered; pin verified');\n    return;\n  }\n  const message = await discord('POST', `/channels/${env.DISCORD_ANNOUNCE_CHANNEL_ID}/messages`, buildDiscordPayload({\n    title: discussion.title,\n    body: discussion.body,\n    url: discussion.url,\n    key,\n  }));\n  await discord('PUT', `/channels/${env.DISCORD_ANNOUNCE_CHANNEL_ID}/pins/${message.id}`);\n  console.log('announcement delivered and pinned');\n}\n","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/discord/release-announce.mjs#L165-L201","documentation":"If no channel webhook is configured, the script falls back to bot-token delivery: it reads recent channel messages via the Discord API to check for an existing receipt, then posts and pins the announcement. This requires DISCORD_BOT_TOKEN and a numeric DISCORD_ANNOUNCE_CHANNEL_ID. It throws this error when either is missing or the channel id is not a 10-25 digit snowflake.","triggerScenarios":"deliver() runs with DISCORD_ANNOUNCE_WEBHOOK_URL unset and either DISCORD_BOT_TOKEN empty or DISCORD_ANNOUNCE_CHANNEL_ID absent/failed the /^\\d{10,25}$/ test.","commonSituations":"Workflow has neither delivery method configured; channel id copied with a prefix or from a server that no longer exists; secrets not passed into the job environment; typos in env var names.","solutions":["Set DISCORD_BOT_TOKEN secret and export it into the workflow env","Set DISCORD_ANNOUNCE_CHANNEL_ID to the numeric channel id (enable Developer Mode in Discord, right-click channel, Copy ID)","Alternatively configure DISCORD_ANNOUNCE_WEBHOOK_URL to use webhook delivery instead","Verify secret names match exactly what the script reads"],"exampleFix":"// before\nDISCORD_ANNOUNCE_CHANNEL_ID: \"#announcements\"\n// after\nDISCORD_ANNOUNCE_CHANNEL_ID: \"1234567890123456789\"","handlingStrategy":"validation","validationCode":"const ok = !!process.env.DISCORD_BOT_TOKEN && /^\\d{10,25}$/.test(process.env.DISCORD_ANNOUNCE_CHANNEL_ID || ''); if (!ok) throw new Error('Set DISCORD_BOT_TOKEN and a numeric DISCORD_ANNOUNCE_CHANNEL_ID');","typeGuard":"const isValidChannelId = (v) => typeof v === 'string' && /^\\d{10,25}$/.test(v);","tryCatchPattern":"try { await deliver(discussion); } catch (e) { if (/credentials are missing or invalid/.test(e.message)) { console.error('Configure bot token + numeric channel id (or a webhook URL)'); process.exit(1); } throw e; }","preventionTips":["Copy the channel id via Discord Developer Mode (right-click → Copy ID), never the channel name","Verify both secrets are attached to the workflow and spelled exactly as the script expects","Pick one delivery mode (webhook or bot token) and configure it completely"],"tags":["discord","configuration","credentials"],"backgroundTag":"missing-credentials","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"}