eyaltoledano/claude-task-master · error · Error

Old tag name is required and must be a string

Error message

Old tag name is required and must be a string

What it means

renameTag() validates its parameters before doing any work. This error is thrown when the oldName argument is missing, null, undefined, an empty string, or not a string type. It is a guard so the tag lookup rawData[oldName] always receives a usable string key.

Source

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

	options = {},
	context = {},
	outputFormat = 'text'
) {
	const { mcpLog, projectRoot } = context;

	// 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 parameters
		if (!oldName || typeof oldName !== 'string') {
			throw new Error('Old tag name is required and must be a string');
		}
		if (!newName || typeof newName !== 'string') {
			throw new Error('New tag name is required and must be a string');
		}

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

		// Prevent renaming master tag
		if (oldName === 'master') {
			throw new Error('Cannot rename the "master" tag');
		}

		// Reserved tag names

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Pass the existing tag name as the second argument to renameTag as a non-empty string
  2. Validate the argument before calling: if (!oldName || typeof oldName !== 'string') throw ...
  3. Check the CLI/MCP layer is actually forwarding the tag parameter instead of dropping it

Example fix

// before
await renameTag(tasksPath, opts.tag, opts.newName);
// after
if (!opts.tag || typeof opts.tag !== 'string') {
  throw new Error('renameTag requires the current tag name');
}
await renameTag(tasksPath, opts.tag, opts.newName);
Defensive patterns

Strategy: validation

Validate before calling

function canRename(oldName, newName) {
  return typeof oldName === 'string' && oldName.length > 0 &&
         typeof newName === 'string' && newName.length > 0;
}
if (!canRename(oldName, newName)) throw new Error('oldName and newName must be non-empty strings');

Type guard

function isNonEmptyString(v) {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  await renameTag(tasksPath, oldName, newName);
} catch (err) {
  if (err.message.includes('Old tag name is required')) {
    console.error(`Invalid source tag argument: ${JSON.stringify(oldName)}`);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling renameTag(tasksPath, oldName, newName, ...) with oldName omitted, passed as undefined/null, as an empty string, or as a non-string (number, object) — e.g. programmatic callers that forward CLI args or MCP tool params without checking they were provided.

Common situations: CLI wrappers forgetting to forward the positional tag argument; MCP tool invocations missing the required parameter; scripting against the API with variables that were never assigned; destructuring mistakes producing undefined.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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