eyaltoledano/claude-task-master · error · Error

Task ${taskId} not found

Error message

Task ${taskId} not found

What it means

updateTaskStatus throws a plain Error `Task ${taskId} not found` when repository.getTask returns null/undefined for the given id. This plain Error is then caught by the method's catch and re-wrapped via wrapError as a STORAGE_ERROR TaskMasterError. It signals the task or subtask ID does not exist in the selected brief on the backend.

Source

Thrown at packages/tm-core/src/modules/storage/adapters/api-storage.ts:687

	/**
	 * Update task or subtask status by ID - for API storage
	 */
	async updateTaskStatus(
		taskId: string,
		newStatus: TaskStatus,
		tag?: string
	): Promise<UpdateStatusResult> {
		await this.ensureInitialized();

		try {
			AuthManager.getInstance().ensureBriefSelected('updateTaskStatus');

			const existingTask = await this.retryOperation(() =>
				this.repository.getTask(this.projectId, taskId)
			);

			if (!existingTask) {
				throw new Error(`Task ${taskId} not found`);
			}

			const oldStatus = existingTask.status;
			if (oldStatus === newStatus) {
				return {
					success: true,
					oldStatus,
					newStatus,
					taskId
				};
			}

			// Update the task/subtask status
			await this.retryOperation(() =>
				this.repository.updateTask(this.projectId, taskId, {
					status: newStatus,
					updatedAt: new Date().toISOString()
				})

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Fetch the current task list (getTask/listTasks) and confirm the id exists in the selected brief
  2. Verify the correct brief/tag is selected before resolving ids
  3. Check subtask id format (e.g. '1.2') matches the backend's current numbering
  4. Handle the not-found case gracefully in scripts: treat as no-op or re-sync ids

Example fix

// before
await storage.updateTaskStatus('5', 'done');
// after
const task = await storage.getTask('5');
if (!task) throw new Error('Re-sync task list; task 5 not in current brief');
await storage.updateTaskStatus('5', 'done');
Defensive patterns

Strategy: validation

Validate before calling

const task = await storage.getTask(taskId);
if (!task) throw new Error(`Task ${taskId} does not exist in the current brief; re-sync ids`);
const VALID = ['pending','in-progress','done','cancelled','deferred'];
if (!VALID.includes(newStatus)) throw new Error(`Invalid status: ${newStatus}`);

Type guard

function isTask(t: unknown): t is Task {
  return typeof t === 'object' && t !== null && typeof (t as Task).id === 'string';
}

Try / catch

try {
  await storage.updateTaskStatus(taskId, 'done', tag);
} catch (e) {
  if (/not found/.test(e.message)) {
    console.warn(`Task ${taskId} not in brief; skipping`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling updateTaskStatus with an id that was deleted, belongs to a different brief/tag, is a malformed subtask id (e.g. wrong '1.2' resolution), or exists only locally and was never pushed to the API.

Common situations: Stale local task list after another session/machine deleted the task; switching briefs and using ids from the old brief; typo in task id; subtask numbering shifted after a server-side change.

Related errors


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