eyaltoledano/claude-task-master · error · Error

"${tagName}" is a reserved tag name

Error message

"${tagName}" is a reserved tag name

What it means

createTag reserves the names 'master', 'main', and 'default' (case-insensitive) because these are the implicit/default tag contexts managed by the library itself. Attempting to create a tag with one of these names throws this error to avoid shadowing or conflicting with built-in tag handling.

Source

Thrown at scripts/modules/task-manager/tag-management.js:99

	// Otherwise, continue with file-based logic below
	try {
		// Validate tag name
		if (!tagName || typeof tagName !== 'string') {
			throw new Error('Tag name is required and must be a string');
		}

		// Validate tag name format (alphanumeric, hyphens, underscores only)
		if (!/^[a-zA-Z0-9_-]+$/.test(tagName)) {
			throw new Error(
				'Tag name can only contain letters, numbers, hyphens, and underscores'
			);
		}

		// Reserved tag names
		const reservedNames = ['master', 'main', 'default'];
		if (reservedNames.includes(tagName.toLowerCase())) {
			throw new Error(`"${tagName}" is a reserved tag name`);
		}

		logFn.info(`Creating new tag: ${tagName}`);

		// Read current tasks data
		const data = readJSON(tasksPath, projectRoot);
		if (!data) {
			throw new Error(`Could not read tasks file at ${tasksPath}`);
		}

		// Use raw tagged data for tag operations - ensure we get the actual tagged structure
		let rawData;
		if (data._rawTaggedData) {
			// If we have _rawTaggedData, use it (this is the clean tagged structure)
			rawData = data._rawTaggedData;
		} else if (data.tasks && !data.master) {
			// This is legacy format - create a master tag structure
			rawData = {

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Choose a different, descriptive tag name (e.g. 'main-copy', 'prod-baseline')
  2. If the goal is the default context, just use the existing default tag instead of creating one
  3. Rename via a distinct name and copy tasks with --copy-from-current if needed

Example fix

// before
await createTag(tasksPath, 'main');
// after
await createTag(tasksPath, 'main-baseline');
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED = ['master', 'main', 'default'];
if (RESERVED.includes(String(tagName).toLowerCase())) {
  throw new Error(`'${tagName}' is reserved; pick another tag name`);
}

Type guard

function isReservedTagName(name) {
  return ['master', 'main', 'default'].includes(String(name).toLowerCase());
}

Try / catch

try {
  await createTag(tasksPath, tagName, {});
} catch (err) {
  if (err.message.includes('is a reserved tag name')) {
    console.error(`Use a distinct name such as '${tagName}-baseline' or operate on the default tag directly.`);
  } else throw err;
}

Prevention

When it happens

Trigger: createTag('master'), createTag('DEFAULT'), or any casing variant of master/main/default; automation generating tags from branch names like 'main'.

Common situations: Scripts syncing git branch names into tags where the main branch is 'main'; users trying to explicitly recreate the default tag.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/7ff5a79daca61f5c. Report an issue: GitHub.