affaan-m/ECC · error · Error

release tag is required

Error message

release tag is required

What it means

releaseMarker builds the HTML comment marker used to locate or create the release announcement discussion. It requires a non-empty tag string; when called with undefined, null, or an empty/whitespace-only string it throws 'release tag is required'. This guards downstream markers like <!-- ecc-release:v1.2.3 --> which would otherwise be ambiguous and match nothing.

Solutions

  1. Invoke the script only for tag push events or pass the tag explicitly: node scripts/discord/release-announce.mjs v1.2.3.
  2. In CI, verify the env var that feeds the tag is populated (e.g. ${GITHUB_REF_NAME}) and pass it to the script.
  3. Add an early guard in the workflow so the job skips (or fails clearly) when the tag is empty.
  4. Strip the refs/tags/ prefix and trim whitespace before calling releaseMarker.

Example fix

// before
const marker = releaseMarker(process.env.RELEASE_TAG);
// after
const rawTag = (process.env.RELEASE_TAG || process.argv[2] || '').replace(/^refs\/tags\//, '').trim();
if (!rawTag) { console.error('No release tag provided'); process.exit(1); }
const marker = releaseMarker(rawTag);
Defensive patterns

Strategy: validation

Validate before calling

function hasReleaseTag(tag) {
  return typeof tag === 'string' && tag.trim().length > 0;
}
if (!hasReleaseTag(process.env.RELEASE_TAG)) process.exit(1);

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  const marker = releaseMarker(tag);
} catch (err) {
  if (err.message === 'release tag is required') {
    console.error('Run this job only on tag push, or pass the tag explicitly.');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: main() or marker calls releaseMarker(tag) with the release tag input from CI/env (e.g. GITHUB_REF_NAME) when no tag is present: running the announcement script outside a tag push, or with RELEASE_TAG unset or whitespace-only.

Common situations: Workflow triggered manually (workflow_dispatch) with no tag input; git tag not yet created; environment variable name mismatch between CI and script; trailing-whitespace-only env value.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at scripts/discord/announcement-core.mjs:11

import { createHash } from 'node:crypto';

const DISCORD_DESCRIPTION_LIMIT = 4000;

export function isAnnouncementDiscussion(discussion) {
  return discussion?.category?.name === 'Announcements';
}

export function releaseMarker(tag) {
  const normalized = String(tag || '').trim();
  if (!normalized) throw new Error('release tag is required');
  return `<!-- ecc-release:${normalized} -->`;
}

export function findReleaseDiscussion(discussions, marker) {
  return discussions.find(item => (
    item?.category?.name === 'Announcements'
    && typeof item.body === 'string'
    && item.body.includes(marker)
  )) || null;
}

export function announcementKey({ repository, discussionId }) {
  if (!/^[^/\s]+\/[^/\s]+$/.test(String(repository || ''))) throw new Error('invalid repository');
  if (!/^[A-Za-z0-9_-]+$/.test(String(discussionId || ''))) throw new Error('invalid discussion id');
  return `${repository}:discussion:${discussionId}`;
}

export function buildDiscordPayload({ title, body, url, key }) {

View on GitHub (pinned to 8321021c54)