eyaltoledano/claude-task-master · error · Error
Task ${taskId} not found
Error message
Task ${taskId} not found What it means
updateTask() loads all tasks for the active tag and searches for one whose id matches taskId. If no task matches, it throws this error rather than silently failing; the caller must supply an ID of an existing task in the current tag.
Source
Thrown at packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts:373
async appendTasks(tasks: Task[], tag?: string): Promise<void> {
const existingTasks = await this.loadTasks(tag);
const allTasks = [...existingTasks, ...tasks];
await this.saveTasks(allTasks, tag);
}
/**
* Update a specific task
*/
async updateTask(
taskId: string,
updates: Partial<Task>,
tag?: string
): Promise<void> {
const tasks = await this.loadTasks(tag);
const taskIndex = tasks.findIndex((t) => String(t.id) === String(taskId));
if (taskIndex === -1) {
throw new Error(`Task ${taskId} not found`);
}
const existingTask = tasks[taskIndex];
// Preserve subtask metadata when subtasks are updated
// AI operations don't include metadata in returned subtasks
let mergedSubtasks = updates.subtasks;
if (updates.subtasks && existingTask.subtasks) {
mergedSubtasks = updates.subtasks.map((updatedSubtask) => {
// Type-coerce IDs for comparison; fall back to title match if IDs don't match
const originalSubtask = existingTask.subtasks?.find(
(st) =>
String(st.id) === String(updatedSubtask.id) ||
(updatedSubtask.title && st.title === updatedSubtask.title)
);
// Merge metadata: preserve original and add/override with new
if (originalSubtask?.metadata || updatedSubtask.metadata) {
return {View on GitHub (pinned to c0c98d367c)
Solutions
- List tasks in the active tag (tmCore.tasks.get() / 'task-master list') and confirm the ID exists
- Pass the correct tag parameter if the task lives in another tag
- Re-check whether the task was deleted or completed and removed
- If parsing user input, validate the ID format before calling
Example fix
// before
await storage.updateTask('42', updates); // throws if task 42 does not exist
// after
const tasks = await storage.loadTasks();
if (tasks.some((t) => String(t.id) === '42')) {
await storage.updateTask('42', updates);
} Defensive patterns
Strategy: validation
Validate before calling
async function taskExists(storage: FileStorage, taskId: string, tag?: string) {
const tasks = await storage.loadTasks(tag);
return tasks.some((t) => String(t.id) === String(taskId));
}
// call only if (await taskExists(storage, '42')) ... Type guard
function isTaskNotFoundError(e: unknown, taskId?: string): e is Error {
return e instanceof Error &&
e.message === `Task ${taskId ?? ''} not found` ||
(e instanceof Error && /^Task .+ not found$/.test(e.message));
} Try / catch
try {
await storage.updateTask(taskId, updates);
} catch (e) {
if (/^Task .+ not found$/.test((e as Error).message)) {
// refresh task list / inform user the ID no longer exists
} else throw e;
} Prevention
- Always resolve task IDs from a fresh loadTasks() call, not stale caches
- Pass the tag explicitly when tasks live outside the default tag
- Validate user-supplied IDs against the current list before updating
- Re-read tasks.json after external processes may have modified it
When it happens
Trigger: Calling updateTask with an ID that does not exist in the active tag's task list, passing a numeric id as a string with unexpected formatting (though matching is done via String() comparison so both '1' and 1 work), or operating against the wrong tag where the task lives under a different tag.
Common situations: Task was deleted by another process/session before the update, hard-coded task IDs from an old tasks.json, CLI user mistypes an ID, or the default tag differs from the tag the task belongs to.
Related errors
- Task ID is required
- Task title is required
- Task description is required
- Task status is required
- Task ${taskId} not found
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/fb79cbea5887b650.
Report an issue: GitHub.