eyaltoledano/claude-task-master · error · Error

Could not read tasks file at ${tasksPath}

Error message

Could not read tasks file at ${tasksPath}

What it means

createTag reads the tasks file with readJSON and throws this error if the read returns null/falsy, meaning the file does not exist, is unparsable, or is empty. Tag operations require the existing tagged structure, so a missing store is fatal.

Source

Thrown at scripts/modules/task-manager/tag-management.js:107

		// Validate tag name format (alphanumeric, hyphens, underscores only)
		if (!/^[a-zA-Z0-9_-]+$/.test(tagName)) {
			throw new Error(
				'Tag name can only contain letters, numbers, hyphens, and underscores'
			);
		}

		// Reserved tag names
		const reservedNames = ['master', 'main', 'default'];
		if (reservedNames.includes(tagName.toLowerCase())) {
			throw new Error(`"${tagName}" is a reserved tag name`);
		}

		logFn.info(`Creating new tag: ${tagName}`);

		// Read current tasks data
		const data = readJSON(tasksPath, projectRoot);
		if (!data) {
			throw new Error(`Could not read tasks file at ${tasksPath}`);
		}

		// Use raw tagged data for tag operations - ensure we get the actual tagged structure
		let rawData;
		if (data._rawTaggedData) {
			// If we have _rawTaggedData, use it (this is the clean tagged structure)
			rawData = data._rawTaggedData;
		} else if (data.tasks && !data.master) {
			// This is legacy format - create a master tag structure
			rawData = {
				master: {
					tasks: data.tasks,
					metadata: data.metadata || {
						created: new Date().toISOString(),
						updated: new Date().toISOString(),
						description: 'Tasks live here by default'
					}
				}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Verify the tasks file exists at the given tasksPath (default .taskmaster/tasks/tasks.json)
  2. Validate/repair the JSON (e.g. with a JSON linter) — fix merge-conflict markers
  3. Initialize tasks first: run 'task-master parse-prd' or 'task-master init' before creating tags
  4. Confirm the --file / tasksPath argument points to the correct file

Example fix

// before
task-master add-tag sprint-1   // fresh repo, no tasks.json
// after
task-master parse-prd prd.txt  // creates tasks.json
task-master add-tag sprint-1
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(tasksPath)) {
  throw new Error(`Tasks file missing at ${tasksPath}; run 'task-master parse-prd' or 'task-master init' first`);
}
JSON.parse(fs.readFileSync(tasksPath, 'utf8')); // throws on corrupt JSON

Type guard

function tasksFileReadable(data) {
  return Boolean(data) && typeof data === 'object';
}

Try / catch

try {
  await createTag(tasksPath, name, {});
} catch (err) {
  if (err.message.startsWith('Could not read tasks file')) {
    console.error(`Ensure ${tasksPath} exists and is valid JSON (init/parse-prd first).`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createTag with a tasksPath where .taskmaster/tasks/tasks.json has not been initialized (no tasks parsed yet), the JSON is corrupted by a failed merge, or the path is wrong.

Common situations: Running add-tag in a fresh repo before 'task-master parse-prd'; merge conflicts leaving invalid JSON; CI checkout missing the .taskmaster directory; passing an incorrect --file path.

Related errors


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