{"record":{"id":"912275e6c29c02ab","repo":"eyaltoledano/claude-task-master","slug":"invalid-subtask-id","errorCode":"INVALID_SUBTASK_ID","errorMessage":"Subtask ID cannot be empty.","messagePattern":"Subtask ID cannot be empty\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mcp-server/src/core/direct-functions/update-subtask-by-id.js","lineNumber":61,"sourceCode":"\t\tif (!tasksJsonPath) {\n\t\t\tconst errorMessage = 'tasksJsonPath is required but was not provided.';\n\t\t\tlogWrapper.error(errorMessage);\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: 'MISSING_ARGUMENT', message: errorMessage }\n\t\t\t};\n\t\t}\n\n\t\t// Basic validation - ID must be present\n\t\t// In API storage, subtask IDs like \"HAM-2611\" are valid (no dot required)\n\t\t// In file storage, subtask IDs must be in format \"parentId.subtaskId\"\n\t\t// The core function handles storage-specific validation\n\t\tif (!id || typeof id !== 'string' || !id.trim()) {\n\t\t\tconst errorMessage = 'Subtask ID cannot be empty.';\n\t\t\tlogWrapper.error(errorMessage);\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: 'INVALID_SUBTASK_ID', message: errorMessage }\n\t\t\t};\n\t\t}\n\n\t\t// At least prompt or metadata is required (validated in MCP tool layer)\n\t\tif (!prompt && !metadata) {\n\t\t\tconst errorMessage =\n\t\t\t\t'No prompt or metadata specified. Please provide information to append or metadata to update.';\n\t\t\tlogWrapper.error(errorMessage);\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: 'MISSING_PROMPT', message: errorMessage }\n\t\t\t};\n\t\t}\n\n\t\tconst subtaskIdStr = String(id).trim();\n\n\t\t// Use the provided path\n\t\tconst tasksPath = tasksJsonPath;","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/mcp-server/src/core/direct-functions/update-subtask-by-id.js#L43-L79","documentation":"The subtask `id` argument must be a non-empty string. updateSubtaskByIdDirect rejects null, undefined, non-string values, or whitespace-only strings with INVALID_SUBTASK_ID before any storage lookup. In API storage IDs like 'HAM-2611' are valid; in file storage the form 'parentId.subtaskId' (e.g. '5.2') is expected — but either way it must be a non-empty string.","triggerScenarios":"Passing id: null/undefined, a number (5.2 as float loses the dotted-string semantics), an empty string, or '  ' when calling the update-subtask-by-id tool.","commonSituations":"JavaScript callers passing numeric subtask IDs (5.02 collapses to 5.2); template strings interpolating an undefined variable into ''; agents hallucinating an ID after a failed task lookup.","solutions":["Pass the subtask ID as a string: id: '5.2' (file storage) or the ticket ID like 'HAM-2611' (API storage).","Verify the value is defined at the call site — log or inspect arguments before the tool call.","If the ID comes from another tool's output, confirm that lookup succeeded and copy the exact ID."],"exampleFix":"// before\nconst id = 5.2; // number — wrong\n// after\nconst id = '5.2'; // dotted string","handlingStrategy":"type-guard","validationCode":"if (typeof id !== 'string' || !id.trim()) throw new Error('subtask id must be a non-empty string');\n// file storage additionally expects 'parentId.subtaskId'\nif (/\\d+\\.\\d+/.test(id) === false && !/^[A-Z]+-\\d+/.test(id)) {\n  console.warn('ID does not look like \"5.2\" or \"HAM-2611\"');\n}","typeGuard":"function isSubtaskId(v) { return typeof v === 'string' && v.trim().length > 0 && (/^\\d+\\.\\d+$/.test(v.trim()) || /^[A-Z]+-\\d+(\\.\\d+)?$/.test(v.trim())); }","tryCatchPattern":null,"preventionTips":["Always quote dotted subtask IDs — numeric 5.2 loses precision and type","Copy IDs verbatim from get-tasks output instead of retyping","Validate IDs with a regex helper before any task/subtask tool call"],"tags":["mcp","validation","invalid-id"],"backgroundTag":"invalid-argument-type","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}