{"record":{"id":"5a26875541e1c692","repo":"eyaltoledano/claude-task-master","slug":"invalid-subtask-id-format-subtaskid-expected-5a2687","errorCode":null,"errorMessage":"Invalid subtask ID format: ${subtaskId}. Expected format: \"parentId.subtaskId\"","messagePattern":"Invalid subtask ID format: (.+?)\\. Expected format: \"parentId\\.subtaskId\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/remove-subtask.js","lineNumber":33,"sourceCode":"\ttasksPath,\n\tsubtaskId,\n\tconvertToTask = false,\n\tgenerateFiles = false,\n\tcontext = {}\n) {\n\tconst { projectRoot, tag } = context;\n\ttry {\n\t\tlog('info', `Removing subtask ${subtaskId}...`);\n\n\t\t// Read the existing tasks with proper context\n\t\tconst data = readJSON(tasksPath, projectRoot, tag);\n\t\tif (!data || !data.tasks) {\n\t\t\tthrow new Error(`Invalid or missing tasks file at ${tasksPath}`);\n\t\t}\n\n\t\t// Parse the subtask ID (format: \"parentId.subtaskId\")\n\t\tif (!subtaskId.includes('.')) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid subtask ID format: ${subtaskId}. Expected format: \"parentId.subtaskId\"`\n\t\t\t);\n\t\t}\n\n\t\tconst [parentIdStr, subtaskIdStr] = subtaskId.split('.');\n\t\tconst parentId = parseInt(parentIdStr, 10);\n\t\tconst subtaskIdNum = parseInt(subtaskIdStr, 10);\n\n\t\t// Find the parent task\n\t\tconst parentTask = data.tasks.find((t) => t.id === parentId);\n\t\tif (!parentTask) {\n\t\t\tthrow new Error(`Parent task with ID ${parentId} not found`);\n\t\t}\n\n\t\t// Check if parent has subtasks\n\t\tif (!parentTask.subtasks || parentTask.subtasks.length === 0) {\n\t\t\tthrow new Error(`Parent task ${parentId} has no subtasks`);\n\t\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/remove-subtask.js#L15-L51","documentation":"removeSubtask only accepts dot-notation subtask IDs like '5.2' (parent.subtask). If the provided subtaskId does not contain a '.', it cannot identify which parent to look under, so this error is thrown.","triggerScenarios":"Calling removeSubtask('5') or removeSubtask('subtask-name') — an ID without a dot separator — where a main task ID or non-numeric label was passed instead of a parent.subtask ID.","commonSituations":"Confusing remove-subtask with remove-task (the latter handles main task IDs), passing a subtask's standalone ID instead of its parent-scoped ID, copying the wrong ID from task listings.","solutions":["Use dot-notation: remove-subtask 5.2 instead of 5.","To delete a main task, use remove-task with the plain task ID instead.","Find the correct parent ID with 'task-master list' or show, then rebuild the parent.subtaskId string."],"exampleFix":"// before\ntask-master remove-subtask --i=7\n// after\ntask-master remove-subtask --i=3.7","handlingStrategy":"validation","validationCode":"if (typeof subtaskId !== 'string' || !/^\\d+\\.\\d+$/.test(subtaskId.trim())) {\n  throw new Error(`subtaskId must be parent.subtask format, got: ${subtaskId}`);\n}","typeGuard":"function isDotSubtaskId(v: unknown): v is string {\n  return typeof v === 'string' && /^\\d+\\.\\d+$/.test(v);\n}","tryCatchPattern":"try {\n  await tmCore.tasks.removeSubtask(tasksPath, subtaskId);\n} catch (err) {\n  if (err.message.includes('Invalid subtask ID format')) {\n    console.error(`'${subtaskId}' is not parent.subtask — use remove-task for main task IDs, or pass e.g. 5.2.`);\n  } else throw err;\n}","preventionTips":["Remember remove-subtask only takes dot-notation IDs; remove-task handles main IDs.","Copy IDs directly from 'task-master list' output instead of typing them.","Normalize/validate ID input in scripts before calling the API.","Trim whitespace from CLI args before passing IDs."],"tags":["validation","task-id","argument-error"],"backgroundTag":"invalid-subtask-id-format","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}