eyaltoledano/claude-task-master · error · TaskMasterError

INVALID_INPUT

INVALID_INPUT

Error message

Project path must be an absolute path, received: "${options.projectPath}"

What it means

TmCore's constructor requires projectPath to be an absolute filesystem path. Relative paths (or values like '.', '~/proj', or URLs) are rejected with a TaskMasterError code INVALID_INPUT, because downstream modules resolve all project files against this path and need it unambiguous.

Source

Thrown at packages/tm-core/src/tm-core.ts:148

	}

	private _options: TmCoreOptions;

	/**
	 * Private constructor - use TmCore.create() instead
	 * This ensures TmCore is always properly initialized
	 */
	private constructor(options: TmCoreOptions) {
		if (!options.projectPath) {
			throw new TaskMasterError(
				'Project path is required',
				ERROR_CODES.MISSING_CONFIGURATION
			);
		}

		// Validate that projectPath is absolute
		if (!path.isAbsolute(options.projectPath)) {
			throw new TaskMasterError(
				`Project path must be an absolute path, received: "${options.projectPath}"`,
				ERROR_CODES.INVALID_INPUT
			);
		}

		// Normalize the path
		this._projectPath = path.resolve(options.projectPath);
		this._options = options;
		// Domain facades will be initialized in initialize()
	}

	/**
	 * Initialize the TmCore instance
	 * Private - only called by the factory method
	 */
	private async initialize(): Promise<void> {
		try {
			// Initialize logger first (before anything else that might log)

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Resolve to absolute before creating: path.resolve(projectPath) in the current working directory context.
  2. Expand tilde manually: projectPath.startsWith('~/') ? path.join(os.homedir(), projectPath.slice(1)) : projectPath.
  3. Log/echo the final absolute path so users can see what is being used.

Example fix

// before
const tmCore = await TmCore.create({ projectPath: userPath }); // e.g. '~/proj'
// after
const resolved = userPath.startsWith('~')
  ? path.join(os.homedir(), userPath.slice(1))
  : path.resolve(userPath);
const tmCore = await TmCore.create({ projectPath: resolved });
Defensive patterns

Strategy: validation

Validate before calling

const path = require('node:path');
if (!path.isAbsolute(projectPath)) {
  projectPath = path.resolve(projectPath);
}

Type guard

const path = require('node:path');
function isAbsolutePath(p) {
  return typeof p === 'string' && path.isAbsolute(p);
}

Try / catch

try {
  const tmCore = await TmCore.create({ projectPath });
} catch (e) {
  if (e instanceof TaskMasterError && e.code === 'INVALID_INPUT') {
    console.error(`projectPath must be absolute; got ${JSON.stringify(e.message)}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling TmCore.create({ projectPath: '.' }) or with relative paths like './myproject', or with tilde-prefixed paths like '~/projects/app' that Node does not expand.

Common situations: Passing CLI/user input straight through without resolution, reusing a relative path from package.json scripts, or tilde paths from shell-style config files.

Related errors


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