{"record":{"id":"30a9bb4c0dc82fa4","repo":"eyaltoledano/claude-task-master","slug":"invalid-format-options-format-valid-formats-a-30a9bb","errorCode":null,"errorMessage":"Invalid format: ${options.format}. Valid formats are: text, json","messagePattern":"Invalid format: (.+?)\\. Valid formats are: text, json","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/cli/src/commands/next.command.ts","lineNumber":105,"sourceCode":"\t\t\tdisplayError(error, { skipExit: true });\n\t\t} finally {\n\t\t\t// Always clean up resources, even on error\n\t\t\tawait this.cleanup();\n\t\t}\n\n\t\t// Exit after cleanup completes\n\t\tif (hasError) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t/**\n\t * Validate command options\n\t */\n\tprivate validateOptions(options: NextCommandOptions): void {\n\t\t// Validate format\n\t\tif (options.format && !['text', 'json'].includes(options.format)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid format: ${options.format}. Valid formats are: text, json`\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize TmCore\n\t */\n\tprivate async initializeCore(projectRoot: string): Promise<void> {\n\t\tif (!this.tmCore) {\n\t\t\tconst resolved = path.resolve(projectRoot);\n\t\t\tthis.tmCore = await createTmCore({ projectPath: resolved });\n\t\t}\n\t}\n\n\t/**\n\t * Get next task from tm-core\n\t */","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/apps/cli/src/commands/next.command.ts#L87-L123","documentation":"For subtask IDs like '1.2', after finding the parent task, updateSingleTaskStatus checks that parentTask.subtasks exists and throws if the parent has none. This means the ID references a subtask under a parent that never had subtasks generated.","triggerScenarios":"Calling setTaskStatus with 'N.M' where task N exists but has an empty or undefined subtasks array, e.g. expand-task was never run on the parent or expansion produced zero subtasks.","commonSituations":"Attempting to status a subtask before running `task-master expand --id=N`; subtask IDs copied from an old tasks.json after regeneration cleared subtasks; assuming all parents have subtasks.","solutions":["Expand the parent task first (`task-master expand --id=N`) to generate subtasks","Verify subtask IDs with `task-master show N` and use an existing subtask ID","Set status on the parent task instead if subtasks are not needed"],"exampleFix":"// before\nawait setTaskStatus(tasksPath, '4.1', 'done'); // task 4 has no subtasks\n// after\nawait expandTask(tasksPath, 4); // generate subtasks\nawait setTaskStatus(tasksPath, '4.1', 'done');","handlingStrategy":"validation","validationCode":"const [parentStr, subStr] = taskId.split('.');\nconst parent = JSON.parse(fs.readFileSync(tasksPath, 'utf8')).tasks.find(t => t.id === parseInt(parentStr, 10));\nif (!parent || !Array.isArray(parent.subtasks) || !parent.subtasks.some(s => s.id === parseInt(subStr, 10))) {\n  throw new Error(`Subtask ${taskId} missing; run 'task-master expand --id=${parentStr}' first`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await setTaskStatus(tasksPath, '4.1', 'done');\n} catch (e) {\n  if (e.message.includes('has no subtasks')) {\n    throw new Error(`Task 4 has no subtasks; run: task-master expand --id=4`);\n  }\n  throw e;\n}","preventionTips":["Run expand-task on parents before referencing subtask IDs","Inspect subtasks with task-master show N before status updates","Regenerate subtask references after tasks.json regeneration"],"tags":["validation","tasks","subtask"],"backgroundTag":"task-not-found","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}