eyaltoledano/claude-task-master · error · Error

Tag "${tagName}" already exists

Error message

Tag "${tagName}" already exists

What it means

Before writing, createTag checks the raw tagged data for an existing entry under the requested tagName. Duplicate tag names are not allowed, so attempting to create a tag that already exists throws this error. Names are compared as exact keys in the raw data object.

Source

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

						created: new Date().toISOString(),
						updated: new Date().toISOString(),
						description: 'Tasks live here by default'
					}
				}
			};
		} else {
			// This is already in tagged format, use it directly but exclude internal fields
			rawData = {};
			for (const [key, value] of Object.entries(data)) {
				if (key !== '_rawTaggedData' && key !== 'tag') {
					rawData[key] = value;
				}
			}
		}

		// Check if tag already exists
		if (rawData[tagName]) {
			throw new Error(`Tag "${tagName}" already exists`);
		}

		// Determine source for copying tasks (only if explicitly requested)
		let sourceTasks = [];
		if (copyFromCurrent || copyFromTag) {
			const sourceTag = copyFromTag || getCurrentTag(projectRoot);
			sourceTasks = getTasksForTag(rawData, sourceTag);

			if (copyFromTag && sourceTasks.length === 0) {
				logFn.warn(`Source tag "${copyFromTag}" not found or has no tasks`);
			}

			logFn.info(`Copying ${sourceTasks.length} tasks from tag "${sourceTag}"`);
		} else {
			logFn.info('Creating empty tag (no tasks copied)');
		}

		// Create the new tag structure in raw data

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Check existing tags with 'task-master tags' and reuse the existing one
  2. If the goal is to copy/refresh, use a versioned name (sprint-1, sprint-2)
  3. In scripts, guard with an existence check before calling createTag

Example fix

// before
await createTag(tasksPath, 'sprint-1'); // throws if exists
// after
if (!rawData['sprint-1']) {
  await createTag(tasksPath, 'sprint-1');
}
Defensive patterns

Strategy: validation

Validate before calling

const raw = JSON.parse(fs.readFileSync(tasksPath, 'utf8'));
if (raw[tagName]) {
  console.log(`Tag '${tagName}' already exists — reusing it`);
} else {
  await createTag(tasksPath, tagName, {});
}

Type guard

function tagIsNew(rawData, name) {
  return Boolean(rawData) && !(name in rawData);
}

Try / catch

try {
  await createTag(tasksPath, name, {});
} catch (err) {
  if (err.message.includes('already exists')) {
    console.log(`Tag '${name}' exists; proceeding with the existing tag.`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createTag with a name already present in tasks.json, e.g. re-running an idempotent-looking script, or creating 'feature-x' when 'feature-x' was created earlier; note the check is case-sensitive so 'Feature-X' would pass this check even if semantically similar.

Common situations: CI pipelines re-running tag creation steps without guards; team members independently creating the same sprint tag; automation deriving names that collide with existing tags.

Related errors


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