eyaltoledano/claude-task-master · error

Invalid or missing tasks file at ${tasksPath}

Error message

Invalid or missing tasks file at ${tasksPath}

What it means

removeSubtask throws this when readJSON on the tasks.json path returns null/undefined or an object without a tasks array. It means the task data file is missing, unreadable, corrupted JSON, or has an unexpected structure.

Source

Thrown at scripts/modules/task-manager/remove-subtask.js:28

 * @param {string} [context.projectRoot] - Project root path
 * @param {string} [context.tag] - Tag for the task
 * @returns {Object|null} The removed subtask if convertToTask is true, otherwise null
 */
async function removeSubtask(
	tasksPath,
	subtaskId,
	convertToTask = false,
	generateFiles = false,
	context = {}
) {
	const { projectRoot, tag } = context;
	try {
		log('info', `Removing subtask ${subtaskId}...`);

		// 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}`);
		}

		// Parse the subtask ID (format: "parentId.subtaskId")
		if (!subtaskId.includes('.')) {
			throw new Error(
				`Invalid subtask ID format: ${subtaskId}. Expected format: "parentId.subtaskId"`
			);
		}

		const [parentIdStr, subtaskIdStr] = subtaskId.split('.');
		const parentId = parseInt(parentIdStr, 10);
		const subtaskIdNum = parseInt(subtaskIdStr, 10);

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

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Run 'task-master init' or create/repair the tasks.json file in the project's .task-master directory.
  2. Confirm you are in the correct project root and using the right --tag.
  3. Validate the JSON file parses (e.g. jq . tasks.json) and contains a top-level "tasks" array.
  4. If the file was deleted, regenerate tasks via parse-prd or restore from version control.

Example fix

// before
{ "tasks": [] } // file missing or renamed to tasks.backup.json
// after
{
  "master": { "tasks": [ ... ] }
} // valid tagged tasks.json restored
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(tasksPath)) throw new Error(`tasks.json not found at ${tasksPath}; run task-master init or parse-prd first`);
const raw = JSON.parse(fs.readFileSync(tasksPath, 'utf8'));
const tasks = raw[tag]?.tasks ?? raw.tasks;
if (!Array.isArray(tasks)) throw new Error('tasks.json has no tasks array for the active tag');

Type guard

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

Try / catch

try {
  await tmCore.tasks.removeSubtask(tasksPath, subtaskId);
} catch (err) {
  if (err.message.startsWith('Invalid or missing tasks file')) {
    console.error('tasks.json missing or corrupt. Re-init or restore it before removing subtasks.');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling removeSubtask with a tasksPath that does not exist, points to an empty/corrupt file, or a file whose parsed JSON lacks the top-level tasks field (including missing tag data).

Common situations: Running remove-subtask before ever initializing tasks (no tasks.json), wrong project root/tag resolving to a nonexistent file path, manual edits that broke JSON structure, or pointing at the wrong tasks file path.

Related errors


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