eyaltoledano/claude-task-master · error · Error

Tasks file not found - initialize project first

Error message

Tasks file not found - initialize project first

What it means

createTag reads tasks.json via modifyJson; when the underlying read fails with ENOENT (the file does not exist), the catch block rethrows it as 'Tasks file not found - initialize project first'. This is a project-bootstrap error: the storage layer cannot manage tags in a project that has never been initialized.

Source

Thrown at packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts:697

							metadata: { ...masterMetadata, tags: ['master'] }
						},
						[tagName]: {
							tasks: tasksToCopy,
							metadata: {
								created: new Date().toISOString(),
								updatedAt: new Date().toISOString(),
								description:
									options?.description ||
									`Tag created on ${new Date().toLocaleDateString()}`,
								tags: [tagName]
							}
						}
					};
				}
			});
		} catch (error: any) {
			if (error.code === 'ENOENT') {
				throw new Error('Tasks file not found - initialize project first');
			}
			throw error;
		}
	}

	/**
	 * Delete a tag from the single tasks.json file
	 * Uses modifyJson for atomic read-modify-write to prevent lost updates
	 */
	async deleteTag(tag: string): Promise<void> {
		const filePath = this.pathResolver.getTasksPath();

		try {
			// Use modifyJson to handle all cases atomically
			let shouldDeleteFile = false;

			await this.fileOps.modifyJson(filePath, (data: any) => {
				if (

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Initialize the project first so tasks.json is created (run the init flow / create the tasks file).
  2. Verify the storage path resolver points at the directory that actually contains tasks.json (check cwd and env-based path overrides).
  3. Restore or regenerate tasks.json if it was deleted or moved.
  4. Check the ENOENT-rooted error in your catch to distinguish missing-file from other createTag failures.

Example fix

// before
await storage.createTag('dev');
// after
const tasksPath = path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json');
if (!fs.existsSync(tasksPath)) {
  await initializeProject(projectRoot); // creates tasks.json
}
await storage.createTag('dev');
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
const tasksPath = path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json');
if (!fs.existsSync(tasksPath)) {
  throw new Error(`Run project init first; missing ${tasksPath}`);
}
await storage.createTag(tagName);

Type guard

function tasksFileExists(projectRoot: string): boolean {
  return fs.existsSync(path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'));
}

Try / catch

try {
  await storage.createTag(tagName);
} catch (err) {
  if (err instanceof Error && err.message.includes('Tasks file not found')) {
    await initializeProject(projectRoot);
    await storage.createTag(tagName);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling createTag in a directory where tasks.json has never been generated; pointing the storage path resolver at the wrong .taskmaster directory; running tag management before running project init; a deleted or moved tasks.json.

Common situations: Running CLI commands outside the project root so the resolver looks in the wrong location; fresh clones missing generated files that are gitignored; misconfigured TASKS_FILE path env var; tests running against temp dirs without initialization.

Related errors


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