eyaltoledano/claude-task-master · error

projectRoot is required for resolveTag

Error message

projectRoot is required for resolveTag

What it means

resolveTag determines the effective tag from options ({projectRoot, tag}), requiring projectRoot because it may need to read state.json/config to resolve the current tag. It throws when projectRoot is absent, even if an explicit tag is supplied (the check precedes tag handling).

Source

Thrown at scripts/modules/utils.js:1809

		// Ignore errors, use hardcoded default
	}

	// Final fallback
	return 'master';
}

/**
 * Resolves the tag to use based on options
 * @param {Object} options - Options object
 * @param {string} options.projectRoot - The project root directory (required)
 * @param {string} [options.tag] - Explicit tag to use
 * @returns {string} The resolved tag name
 */
function resolveTag(options = {}) {
	const { projectRoot, tag } = options;

	if (!projectRoot) {
		throw new Error('projectRoot is required for resolveTag');
	}

	// If explicit tag provided, use it
	if (tag) {
		return tag;
	}

	// Otherwise get current tag from state/config
	return getCurrentTag(projectRoot);
}

/**
 * Gets the tasks array for a specific tag from tagged tasks.json data
 * @param {Object} data - The parsed tasks.json data (after migration)
 * @param {string} tagName - The tag name to get tasks for
 * @returns {Array} The tasks array for the specified tag, or empty array if not found
 */
function getTasksForTag(data, tagName) {

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Always include projectRoot in the options object: resolveTag({ projectRoot, tag })
  2. Obtain projectRoot via findProjectRoot() before building options
  3. If only the explicit tag matters, return the tag directly in your caller instead of invoking resolveTag without a root

Example fix

// before
resolveTag({ tag: 'master' });
// after
resolveTag({ projectRoot: '/path/to/project', tag: 'master' });
Defensive patterns

Strategy: validation

Validate before calling

const opts = { projectRoot: findProjectRoot(), tag: explicitTag };
if (!opts.projectRoot) throw new Error('resolveTag requires a project root');
const tag = resolveTag(opts);

Type guard

const validTagOptions = (o) => !!o && typeof o === 'object' && typeof o.projectRoot === 'string' && o.projectRoot.trim() !== '';

Try / catch

try {
  const tag = resolveTag(options);
} catch (e) {
  if (e.message === 'projectRoot is required for resolveTag') {
    // supply explicit tag or resolve projectRoot first
  } else throw e;
}

Prevention

When it happens

Trigger: Calling resolveTag({}) or resolveTag({ tag: 'master' }) without projectRoot from API/MCP code that skipped root resolution.

Common situations: Integrations hardcoding a tag but forgetting projectRoot, wrappers around readJSON/writeJSON constructing options dynamically where projectRoot ends up undefined, or tests calling resolveTag with partial options.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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