eyaltoledano/claude-task-master · error

Invalid or missing tasks file at ${tasksPath}

Error message

Invalid or missing tasks file at ${tasksPath}

What it means

addSubtask throws this when readJSON on the tasks file returns nothing usable — either the file does not exist, is unparseable, or the parsed object has no 'tasks' array. addSubtask needs the full task list to locate the parent task and write back changes, so it fails fast before mutating anything.

Source

Thrown at scripts/modules/task-manager/add-subtask.js:31

 * @param {string} context.tag - Tag for the task
 * @returns {Object} The newly created or converted subtask
 */
async function addSubtask(
	tasksPath,
	parentId,
	existingTaskId = null,
	newSubtaskData = null,
	generateFiles = false,
	context = {}
) {
	const { projectRoot, tag } = context;
	try {
		log('info', `Adding subtask to parent task ${parentId}...`);

		// Read the existing tasks with proper context
		const data = readJSON(tasksPath, projectRoot, tag);
		if (!data || !data.tasks) {
			throw new Error(`Invalid or missing tasks file at ${tasksPath}`);
		}

		// Convert parent ID to number
		const parentIdNum = parseInt(parentId, 10);

		// Find the parent task
		const parentTask = data.tasks.find((t) => t.id === parentIdNum);
		if (!parentTask) {
			throw new Error(`Parent task with ID ${parentIdNum} not found`);
		}

		// Initialize subtasks array if it doesn't exist
		if (!parentTask.subtasks) {
			parentTask.subtasks = [];
		}

		let newSubtask;

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Verify tasksPath points to an existing, valid tasks JSON file (e.g. .taskmaster/tasks.json).
  2. If the file is missing, initialize it (run task-master init or create the file with {"tasks":[]}).
  3. Validate the JSON parses (e.g. node -e "require(path)") and contains a 'tasks' array.
  4. Re-run the add-subtask command from the correct project root.

Example fix

// before (missing file)
addSubtask('tasks/missing.json', '1', { title: 'Sub' });
// after
// create .taskmaster/tasks.json with {"tasks":[...]} first
addSubtask('.taskmaster/tasks.json', '1', { title: 'Sub' });
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
function assertValidTasksFile(tasksPath) {
  if (!fs.existsSync(tasksPath)) throw new Error(`${tasksPath} does not exist`);
  const data = JSON.parse(fs.readFileSync(tasksPath, 'utf8'));
  if (!data || !Array.isArray(data.tasks)) throw new Error(`${tasksPath} has no tasks array`);
  return data;
}

Type guard

function isTasksData(d) {
  return typeof d === 'object' && d !== null && Array.isArray(d.tasks);
}

Try / catch

try {
  await addSubtask(tasksPath, parentId, opts);
} catch (err) {
  if (err.message.startsWith('Invalid or missing tasks file')) {
    // initialize or repair the tasks file, then retry once
  } else throw err;
}

Prevention

When it happens

Trigger: Calling addSubtask with a tasksPath that points to a non-existent, empty, corrupted, or schema-invalid JSON file, or one whose top-level object lacks 'tasks'.

Common situations: Running commands in the wrong project directory (no .taskmaster/tasks.json), a failed earlier write truncating the file, or pointing at a different tag file that was never initialized.

Related errors


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