{"record":{"id":"f7aa2ce1de38cb22","repo":"eyaltoledano/claude-task-master","slug":"parent-task-no-subtasks","errorCode":"PARENT_TASK_NO_SUBTASKS","errorMessage":"Source parent task ${sourceParentId} has no subtasks","messagePattern":"Source parent task (.+?) has no subtasks","errorType":"exception","errorClass":"MoveTaskError","httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/move-task.js","lineNumber":317,"sourceCode":"\nfunction moveSubtaskToTask(tasks, sourceId, destinationId) {\n\t// Parse source ID\n\tconst [sourceParentId, sourceSubtaskId] = sourceId\n\t\t.split('.')\n\t\t.map((id) => parseInt(id, 10));\n\tconst destTaskId = parseInt(destinationId, 10);\n\n\t// Find source parent and destination task\n\tconst sourceParentTask = tasks.find((t) => t.id === sourceParentId);\n\n\tif (!sourceParentTask) {\n\t\tthrow new MoveTaskError(\n\t\t\tMOVE_ERROR_CODES.PARENT_TASK_NOT_FOUND,\n\t\t\t`Source parent task with ID ${sourceParentId} not found`\n\t\t);\n\t}\n\tif (!sourceParentTask.subtasks) {\n\t\tthrow new MoveTaskError(\n\t\t\tMOVE_ERROR_CODES.PARENT_TASK_NO_SUBTASKS,\n\t\t\t`Source parent task ${sourceParentId} has no subtasks`\n\t\t);\n\t}\n\n\t// Find source subtask\n\tconst sourceSubtaskIndex = sourceParentTask.subtasks.findIndex(\n\t\t(st) => st.id === sourceSubtaskId\n\t);\n\tif (sourceSubtaskIndex === -1) {\n\t\tthrow new MoveTaskError(\n\t\t\tMOVE_ERROR_CODES.SUBTASK_NOT_FOUND,\n\t\t\t`Source subtask ${sourceId} not found`\n\t\t);\n\t}\n\n\tconst sourceSubtask = sourceParentTask.subtasks[sourceSubtaskIndex];\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/move-task.js#L299-L335","documentation":"When promoting a subtask to a task, after confirming the source parent exists, moveSubtaskToTask checks that the parent actually has a subtasks array. If sourceParentTask.subtasks is undefined/null (task has never had subtasks), it throws MoveTaskError with code PARENT_TASK_NO_SUBTASKS.","triggerScenarios":"Calling moveTask('5.2', '9') where task 5 exists but has no subtasks property at all — note a task with an empty [] array passes this check and fails later with SUBTASK_NOT_FOUND; the '.2' subtask part references a subtask on a childless task.","commonSituations":"Copy/paste or scripted ID lists pointing a subtask ID at the wrong parent; task's subtasks were all moved away and the (now empty) handling differs by code path; hand-edited tasks.json removed the subtasks key entirely.","solutions":["Check `task-master show 5` to confirm the parent actually has the subtask you reference","Fix the source ID to point at a parent that has subtasks","If tasks.json is hand-edited and subtasks key is missing, restore the key or regenerate task files","Guard programmatically: check Array.isArray(task.subtasks) && task.subtasks.some(s => s.id === subId) before calling moveTask"],"exampleFix":"// before (task 5 has no subtasks)\ntask-master move --from=5.2 --to=9\n// after\ntask-master show 5   # no subtasks; the subtask is under 6:\ntask-master move --from=6.2 --to=9","handlingStrategy":"type-guard","validationCode":"function assertParentHasSubtasks(tasks, sourceId) {\n  const parentId = parseInt(String(sourceId).split('.')[0], 10);\n  const parent = tasks.find((t) => t.id === parentId);\n  if (!parent) throw new Error(`Parent ${parentId} not found`);\n  if (!Array.isArray(parent.subtasks)) throw new Error(`Parent ${parentId} has no subtasks`);\n}","typeGuard":"function parentWithSubtasks(task) {\n  return typeof task === 'object' && task !== null && Array.isArray(task.subtasks) && task.subtasks.length > 0;\n}","tryCatchPattern":"try {\n  await moveTask(tasksPath, '5.2', '9', false, { projectRoot, tag });\n} catch (err) {\n  if (err.name === 'MoveTaskError' && err.code === 'PARENT_TASK_NO_SUBTASKS') {\n    console.error(`Task has no subtasks — verify with 'task-master show' before moving '5.x'`);\n  } else throw err;\n}","preventionTips":["Check `task-master show <parentId>` shows subtasks before referencing 'X.Y'","Validate with Array.isArray(task.subtasks) && subtasks.some(s => s.id === n) in scripts","Don't assume a subtask ordinal belongs to a given parent — IDs are local to each parent","Restore a missing subtasks key if tasks.json was hand-edited"],"tags":["task-move","subtask","validation"],"backgroundTag":"parent-has-no-subtasks","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}