eyaltoledano/claude-task-master · error · Error

Tag name can only contain letters, numbers, hyphens, and und

Error message

Tag name can only contain letters, numbers, hyphens, and underscores

What it means

createTag enforces a tag-name format of /^[a-zA-Z0-9_-]+$/ — letters, numbers, hyphens, and underscores only. Names containing spaces, slashes, dots, unicode, or other special characters are rejected because tags are used as JSON keys and path/branch-safe identifiers.

Source

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

			throw new Error(remoteResult.message || 'Remote tag creation failed');
		}
		if (outputFormat === 'json') {
			return remoteResult;
		}
		// For text output, the bridge already displayed the message
		return remoteResult;
	}

	// 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}`);
		}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Sanitize the name: replace invalid characters with hyphens or underscores
  2. Lowercase/kebab-case the name before calling createTag
  3. Trim whitespace from user-provided or branch-derived names

Example fix

// before
await createTag(tasksPath, 'feature/login v2');
// after
const safe = 'feature/login v2'.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-|-$/g, '');
await createTag(tasksPath, safe); // feature-login-v2
Defensive patterns

Strategy: validation

Validate before calling

if (!/^[a-zA-Z0-9_-]+$/.test(tagName)) {
  throw new Error(`Invalid tag name '${tagName}'; use letters, numbers, hyphens, underscores only`);
}

Type guard

function isSafeTagName(name) {
  return typeof name === 'string' && /^[a-zA-Z0-9_-]+$/.test(name);
}

Try / catch

try {
  await createTag(tasksPath, tagName, {});
} catch (err) {
  if (err.message.includes('can only contain letters, numbers, hyphens')) {
    const safe = tagName.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-+|-+$/g, '');
    await createTag(tasksPath, safe, {});
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createTag with names like 'my tag', 'v1.0', 'feature/x', 'réparation', or any name with punctuation outside [A-Za-z0-9_-].

Common situations: Deriving tag names from branch names ('feature/login'), version strings ('2.1.0'), or user input with spaces; pasting names with trailing whitespace.

Related errors


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