eyaltoledano/claude-task-master · error
Invalid or missing tasks file at ${tasksPath}
Error message
Invalid or missing tasks file at ${tasksPath} What it means
removeSubtask throws this when readJSON on the tasks.json path returns null/undefined or an object without a tasks array. It means the task data file is missing, unreadable, corrupted JSON, or has an unexpected structure.
Source
Thrown at scripts/modules/task-manager/remove-subtask.js:28
* @param {string} [context.projectRoot] - Project root path
* @param {string} [context.tag] - Tag for the task
* @returns {Object|null} The removed subtask if convertToTask is true, otherwise null
*/
async function removeSubtask(
tasksPath,
subtaskId,
convertToTask = false,
generateFiles = false,
context = {}
) {
const { projectRoot, tag } = context;
try {
log('info', `Removing subtask ${subtaskId}...`);
// Read the existing tasks with proper context
const data = readJSON(tasksPath, projectRoot, tag);
if (!data || !data.tasks) {
throw new Error(`Invalid or missing tasks file at ${tasksPath}`);
}
// Parse the subtask ID (format: "parentId.subtaskId")
if (!subtaskId.includes('.')) {
throw new Error(
`Invalid subtask ID format: ${subtaskId}. Expected format: "parentId.subtaskId"`
);
}
const [parentIdStr, subtaskIdStr] = subtaskId.split('.');
const parentId = parseInt(parentIdStr, 10);
const subtaskIdNum = parseInt(subtaskIdStr, 10);
// Find the parent task
const parentTask = data.tasks.find((t) => t.id === parentId);
if (!parentTask) {
throw new Error(`Parent task with ID ${parentId} not found`);
}View on GitHub (pinned to c0c98d367c)
Solutions
- Run 'task-master init' or create/repair the tasks.json file in the project's .task-master directory.
- Confirm you are in the correct project root and using the right --tag.
- Validate the JSON file parses (e.g. jq . tasks.json) and contains a top-level "tasks" array.
- If the file was deleted, regenerate tasks via parse-prd or restore from version control.
Example fix
// before
{ "tasks": [] } // file missing or renamed to tasks.backup.json
// after
{
"master": { "tasks": [ ... ] }
} // valid tagged tasks.json restored Defensive patterns
Strategy: validation
Validate before calling
import fs from 'fs';
if (!fs.existsSync(tasksPath)) throw new Error(`tasks.json not found at ${tasksPath}; run task-master init or parse-prd first`);
const raw = JSON.parse(fs.readFileSync(tasksPath, 'utf8'));
const tasks = raw[tag]?.tasks ?? raw.tasks;
if (!Array.isArray(tasks)) throw new Error('tasks.json has no tasks array for the active tag'); Type guard
function isValidTasksData(d) {
return d != null && typeof d === 'object' &&
Array.isArray((d as any).tasks);
} Try / catch
try {
await tmCore.tasks.removeSubtask(tasksPath, subtaskId);
} catch (err) {
if (err.message.startsWith('Invalid or missing tasks file')) {
console.error('tasks.json missing or corrupt. Re-init or restore it before removing subtasks.');
} else throw err;
} Prevention
- Always initialize the project (task-master init / parse-prd) before task mutations.
- Validate tasks.json with a JSON parser after manual edits.
- Commit tasks.json (or back it up) so it can be restored.
- Run commands from the correct project root.
- Keep tooling and scripts updated so file paths resolve consistently.
When it happens
Trigger: Calling removeSubtask with a tasksPath that does not exist, points to an empty/corrupt file, or a file whose parsed JSON lacks the top-level tasks field (including missing tag data).
Common situations: Running remove-subtask before ever initializing tasks (no tasks.json), wrong project root/tag resolving to a nonexistent file path, manual edits that broke JSON structure, or pointing at the wrong tasks file path.
Related errors
- Could not read tasks file at ${tasksPath}
- ${pathType} override path does not exist: ${resolvedPath}
- Project root override path does not exist: ${resolvedOverrid
- MISSING_ARGUMENT
- MISSING_ARGUMENT
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/3917866db951d499.
Report an issue: GitHub.