eyaltoledano/claude-task-master · error · Error

Failed to load metadata: ${error.message}

Error message

Failed to load metadata: ${error.message}

What it means

loadMetadata() reads tasks.json and extracts per-tag metadata via the format handler. Missing file (ENOENT) returns null; any other failure reading or parsing the file is rethrown as 'Failed to load metadata'.

Source

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

			throw new Error(`Failed to get tags: ${error.message}`);
		}
	}

	/**
	 * Load metadata from the single tasks.json file for a specific tag
	 */
	async loadMetadata(tag?: string): Promise<TaskMetadata | null> {
		const filePath = this.pathResolver.getTasksPath();
		const resolvedTag = tag || 'master';

		try {
			const rawData = await this.fileOps.readJson(filePath);
			return this.formatHandler.extractMetadata(rawData, resolvedTag);
		} catch (error: any) {
			if (error.code === 'ENOENT') {
				return null;
			}
			throw new Error(`Failed to load metadata: ${error.message}`);
		}
	}

	/**
	 * Save metadata (stored with tasks)
	 */
	async saveMetadata(_metadata: TaskMetadata, tag?: string): Promise<void> {
		const tasks = await this.loadTasks(tag);
		await this.saveTasks(tasks, tag);
	}

	/**
	 * Append tasks to existing storage
	 */
	async appendTasks(tasks: Task[], tag?: string): Promise<void> {
		const existingTasks = await this.loadTasks(tag);
		const allTasks = [...existingTasks, ...tasks];
		await this.saveTasks(allTasks, tag);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Read error.message to determine whether it's a parse or access problem
  2. Validate and fix tasks.json JSON syntax
  3. Restore tasks.json from git/backup if corrupted
  4. Confirm the storage adapter is pointed at the correct .taskmaster directory

Example fix

// before: metadata replaced with invalid fragment by hand edit
{ "metadata": { "created": , }, "tags": {} }
// after
{ "metadata": { "created": "2026-01-01T00:00:00Z" }, "tags": {} }
Defensive patterns

Strategy: try-catch

Validate before calling

function metadataIsParseable(path = '.taskmaster/tasks.json') {
  try {
    const d = JSON.parse(readFileSync(path, 'utf8'));
    return d.metadata === undefined || (typeof d.metadata === 'object' && d.metadata !== null);
  } catch { return false; }
}

Type guard

function isLoadMetadataError(e: unknown): e is Error {
  return e instanceof Error && e.message.startsWith('Failed to load metadata:');
}

Try / catch

try {
  const meta = await storage.loadMetadata(tag); // null on ENOENT is expected
} catch (e) {
  if (isLoadMetadataError(e)) {
    // repair tasks.json or restore from backup before retrying
  } else throw e;
}

Prevention

When it happens

Trigger: Malformed JSON in tasks.json, EACCES or other fs errors during readJson, extractMetadata failing on an unexpected raw data shape (e.g. metadata not an object), or storage path misconfiguration.

Common situations: tasks.json corrupted by concurrent writes, metadata section deleted during a manual edit, format version mismatch between the stored file and the current format handler, or wrong storage root configured.

Related errors


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