eyaltoledano/claude-task-master · error

Could not read tasks file at ${tasksPath}

Error message

Could not read tasks file at ${tasksPath}

What it means

removeTask reads the tasks file once via readJSON before processing IDs. If readJSON returns a falsy value — file missing, empty, or unparseable — this error is thrown before any task removal happens.

Source

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

		errors: [],
		removedTasks: []
	};
	const taskIdsToRemove = taskIds
		.split(',')
		.map((id) => id.trim())
		.filter(Boolean); // Remove empty strings if any

	if (taskIdsToRemove.length === 0) {
		results.success = false;
		results.errors.push('No valid task IDs provided.');
		return results;
	}

	try {
		// Read the tasks file ONCE before the loop, preserving the full tagged structure
		const rawData = readJSON(tasksPath, projectRoot, tag); // Read raw data
		if (!rawData) {
			throw new Error(`Could not read tasks file at ${tasksPath}`);
		}

		// Use the full tagged data if available, otherwise use the data as is
		const fullTaggedData = rawData._rawTaggedData || rawData;

		if (!fullTaggedData[tag] || !fullTaggedData[tag].tasks) {
			throw new Error(`Tag '${tag}' not found or has no tasks.`);
		}

		const tasks = fullTaggedData[tag].tasks; // Work with tasks from the correct tag

		const tasksToDeleteFiles = []; // Collect IDs of main tasks whose files should be deleted

		for (const taskId of taskIdsToRemove) {
			// Check if the task ID exists *before* attempting removal
			if (!taskExists(tasks, taskId)) {
				const errorMsg = `Task with ID ${taskId} in tag '${tag}' not found or already removed.`;
				results.errors.push(errorMsg);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Create or restore tasks.json: run init/parse-prd or restore from git.
  2. Confirm the file exists and is valid JSON at the resolved path (jq . tasks.json).
  3. Run from the correct project root or pass the correct project-root option.
  4. Check file permissions so the process can read the file.

Example fix

// before
.task-master/tasks.json  // empty file after failed write
// after
{
  "master": { "tasks": [ ... ] }
} // restored via `git checkout -- .task-master/tasks.json`
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(tasksPath) || fs.statSync(tasksPath).size === 0) {
  throw new Error(`tasks.json missing or empty at ${tasksPath}; run task-master init or restore it`);
}
JSON.parse(fs.readFileSync(tasksPath, 'utf8')); // throws on corrupt JSON

Type guard

function isReadableTasksFile(p) {
  try {
    return fs.existsSync(p) && JSON.parse(fs.readFileSync(p, 'utf8')) != null;
  } catch { return false; }
}

Try / catch

try {
  await tmCore.tasks.removeTask(tasksPath, taskIds);
} catch (err) {
  if (err.message.startsWith('Could not read tasks file')) {
    console.error(`Cannot read ${tasksPath}. Check existence, permissions, and JSON validity.`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling removeTask with a tasksPath pointing to a nonexistent, empty, or corrupt tasks.json, or a path with wrong permissions preventing a valid read.

Common situations: Running remove-task before init/parse-prd ever created tasks.json, wrong --project-root or working directory, file corrupted by a failed write or manual edit.

Related errors


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