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
- Always include projectRoot in the options object: resolveTag({ projectRoot, tag })
- Obtain projectRoot via findProjectRoot() before building options
- 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
- Build options objects centrally so projectRoot is always set
- Pass { projectRoot, tag } together from callers
- Assert projectRoot presence in wrapper functions before tag resolution
- Default to findProjectRoot() when callers omit the root
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
- projectRoot is required for getCurrentTag
- MISSING_PARAMETER
- NOT_IMPLEMENTED
- Failed to get tags: ${error.message}
- Tag ${oldTag} not found - file doesn't exist
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/62c16d8e6ed356a8.
Report an issue: GitHub.