eyaltoledano/claude-task-master · error
TASK_NOT_FOUND
TASK_NOT_FOUND
Error message
Task with ID ${taskId} not found What it means
After loading tasks and searching for the requested ID, expandTaskDirect returns this TASK_NOT_FOUND error when no task in the file matches taskId. The taskId in the message is the parsed integer, so IDs as strings vs numbers are normalized before lookup.
Source
Thrown at mcp-server/src/core/direct-functions/expand-task.js:130
return {
success: false,
error: {
code: 'INVALID_TASKS_FILE',
message: `No valid tasks found in ${tasksPath}. readJSON returned: ${JSON.stringify(data)}`
}
};
}
// Find the specific task
log.info(`[expandTaskDirect] Searching for task ID ${taskId} in data`);
const task = data.tasks.find((t) => t.id === taskId);
log.info(`[expandTaskDirect] Task found: ${task ? 'Yes' : 'No'}`);
if (!task) {
return {
success: false,
error: {
code: 'TASK_NOT_FOUND',
message: `Task with ID ${taskId} not found`
}
};
}
// Check if task is completed
if (task.status === 'done' || task.status === 'completed') {
return {
success: false,
error: {
code: 'TASK_COMPLETED',
message: `Task ${taskId} is already marked as ${task.status} and cannot be expanded`
}
};
}
// Check for existing subtasks and force flag
const hasExistingSubtasks = task.subtasks && task.subtasks.length > 0;View on GitHub (pinned to c0c98d367c)
Solutions
- List tasks (list/read tasks.json) and confirm the exact ID, then retry with a valid one.
- If targeting a subtask, use the subtask-specific expansion parameters/tool instead of ID '3.1'.
- Re-run parse-prd or check for re-numbering if IDs shifted after regeneration.
- Guard the call: verify the task exists in the file before invoking expand.
Example fix
// before
await expandTaskDirect({ tasksJsonPath, id: '12' }); // only 9 tasks exist
// after
const { tasks } = JSON.parse(fs.readFileSync(tasksJsonPath, 'utf8'));
if (tasks.some(t => t.id === 12)) {
await expandTaskDirect({ tasksJsonPath, id: '12' });
} Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
function taskExists(p, id) {
const data = JSON.parse(fs.readFileSync(p, 'utf8'));
return Array.isArray(data.tasks) && data.tasks.some(t => t.id === parseInt(id, 10));
}
if (!taskExists(tasksJsonPath, id)) {
throw new Error(`Task ${id} not in ${tasksJsonPath}; refresh the task list first`);
} Type guard
function findTask(data, id) {
if (!data || !Array.isArray(data.tasks)) return undefined;
return data.tasks.find(t => t.id === parseInt(id, 10));
} Try / catch
const res = await expandTaskDirect(args);
if (!res.success && res.error?.code === 'TASK_NOT_FOUND') {
// re-list tasks and retry with a valid ID instead of failing the workflow
const tasks = listTaskIds(tasksJsonPath);
console.warn(`ID ${args.id} missing. Available: ${tasks.join(', ')}`);
} Prevention
- Fetch the current task list before referencing IDs in automated flows.
- Re-read tasks.json after any regeneration — IDs may be renumbered.
- Route subtask expansion to the subtask-specific tool/parameters.
- Never trust LLM-recalled IDs; validate against the file first.
When it happens
Trigger: Calling expand_task with an ID that does not exist in tasks.json (typo, out of range, task deleted), or passing a subtask ID ('3.1') to a lookup that only searches top-level tasks, or stale ID references after re-numbering from parse-prd.
Common situations: Regenerating tasks invalidates previously known IDs; agent-supplied IDs hallucinated by the LLM; trying to expand a completed/removed task; referencing subtask IDs through the top-level task tool.
Related errors
- Task with ID ${taskId} not found in tag '${tag}'
- Task with ID ${taskId} not found
- INPUT_VALIDATION_ERROR
- Template "${templateName}" not found
- Task ${taskId} not found
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/5f8f3af3c573e12f.
Report an issue: GitHub.