eyaltoledano/claude-task-master · error

projectRoot is required in args to resolve project paths

Error message

projectRoot is required in args to resolve project paths

What it means

resolveProjectPath in mcp-server's path-utils requires args.projectRoot to resolve any relative project path. Without it, the tool cannot anchor relativePath to a project directory, so it throws immediately to prevent writing/reading files relative to an arbitrary working directory.

Source

Thrown at mcp-server/src/core/utils/path-utils.js:182

			{ projectRoot, tag },
			log
		);
	}

	// Fallback to core function without projectRoot context
	return coreFindComplexityReportPath(explicitPath, null, log);
}

/**
 * Resolve any project-relative path from arguments
 * @param {string} relativePath - Relative path to resolve
 * @param {Object} args - Arguments object containing projectRoot
 * @returns {string} - Resolved absolute path
 */
export function resolveProjectPath(relativePath, args) {
	// Ensure we have a projectRoot from args
	if (!args?.projectRoot) {
		throw new Error('projectRoot is required in args to resolve project paths');
	}

	// Normalize the project root to prevent double .taskmaster paths
	const projectRoot = normalizeProjectRoot(args.projectRoot);

	// If already absolute, return as-is
	if (path.isAbsolute(relativePath)) {
		return relativePath;
	}

	// Resolve relative to normalized projectRoot
	return path.resolve(projectRoot, relativePath);
}

/**
 * Find project root using core utility
 * @param {string} [startDir] - Directory to start searching from
 * @returns {string|null} - Project root path or null if not found

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Pass projectRoot (absolute path to the Task Master project) in the tool's args object
  2. Initialize the project first (task-master init) so the MCP server has a project root to use
  3. Check the MCP tool call payload — ensure the argument is named projectRoot and is non-empty

Example fix

// before
callTool('taskmaster', 'outputPath', { relativePath: 'tasks.json' })
// after
callTool('taskmaster', 'outputPath', { relativePath: 'tasks.json', projectRoot: '/abs/path/to/project' })
Defensive patterns

Strategy: validation

Validate before calling

function assertProjectRoot(args) {
  if (!args || typeof args.projectRoot !== 'string' || args.projectRoot.length === 0) {
    throw new Error('projectRoot (non-empty string) is required in args');
  }
}

Type guard

function hasProjectRoot(args) {
  return typeof args === 'object' && args !== null &&
    typeof args.projectRoot === 'string' && args.projectRoot.length > 0;
}

Try / catch

try { const p = resolveProjectPath(rel, args); } catch (e) {
  if (e.message.includes('projectRoot is required')) { /* prompt user for project root */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling an MCP tool (e.g. via outputPath) that resolves project paths with an args object lacking projectRoot, or with projectRoot null/undefined.

Common situations: MCP client omits projectRoot in tool arguments; tools invoked before project initialization; schema allows optional projectRoot but the resolver requires it.

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/52cebb2ec1e89256. Report an issue: GitHub.