eyaltoledano/claude-task-master · error · Error

Cannot delete the "master" tag

Error message

Cannot delete the "master" tag

What it means

The 'master' tag is the default/root tag in task-master's tagged tasks.json format. deleteTag() hard-blocks deleting it because removing it would leave the project with no default tag and break the current-tag pointer. This is an intentional protection, not a bug.

Source

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

	// Create a consistent logFn object regardless of context
	const logFn = mcpLog || {
		info: (...args) => log('info', ...args),
		warn: (...args) => log('warn', ...args),
		error: (...args) => log('error', ...args),
		debug: (...args) => log('debug', ...args),
		success: (...args) => log('success', ...args)
	};

	try {
		// Validate tag name
		if (!tagName || typeof tagName !== 'string') {
			throw new Error('Tag name is required and must be a string');
		}

		// Prevent deletion of master tag
		if (tagName === 'master') {
			throw new Error('Cannot delete the "master" tag');
		}

		logFn.info(`Deleting 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. Do not delete 'master'; delete the specific tag you intended instead.
  2. If master's contents are unwanted, switch to a new tag (useTag) and delete tasks individually, or clear tasks within master.
  3. If you truly need a fresh start, create a new tagged tasks.json rather than deleting master from an existing one.

Example fix

// before
await deleteTag(tasksPath, 'master', { yes: true }, context);
// after
const target = tag === 'master' ? null : tag;
if (!target) throw new Error('Refusing to delete the master tag; pick another tag');
await deleteTag(tasksPath, target, { yes: true }, context);
Defensive patterns

Strategy: validation

Validate before calling

if (tagName === 'master') {
  throw new Error('The master tag cannot be deleted; choose another tag');
}

Try / catch

// Treat as expected refusal, not a crash
try {
  await deleteTag(tasksPath, tag, opts, ctx);
} catch (e) {
  if (e.message.includes('master')) {
    console.warn('Skipping protected master tag');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling deleteTag(tasksPath, 'master', ...) directly, or a CLI/MCP wrapper forwarding 'master' as the tag name to `task-master delete-tag master`.

Common situations: Users trying to 'clean up' their tasks file by removing the default tag, batch-delete scripts iterating all tags including master, or automation that forgot to filter out 'master' from a tag list.

Related errors


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